import java.io.*;
import java.util.*;
public class PatternSearch {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("How many lines you want to read from the text file?");
int numLines = scanner.nextInt();
scanner.nextLine();
System.out.println("How many patterns to be generated?");
int numPatterns = scanner.nextInt();
scanner.nextLine();
System.out.println("What is the length of each pattern?");
int patternLength = scanner.nextInt();
scanner.nextLine();
StringBuilder textBuilder = new StringBuilder();
try (BufferedReader br = new BufferedReader(new FileReader("input.txt"))) {
String line;
int linesRead = 0;
while ((line = br.readLine()) != null && linesRead < numLines) {
textBuilder.append(line.toLowerCase());
textBuilder.append("\n");
linesRead++;
}
} catch (IOException e) {
e.printStackTrace();
return;
}
String text = textBuilder.toString();
List<String> patterns = generateRandomPatterns(text, numPatterns, patternLength);
try (PrintWriter writer = new PrintWriter("patterns.txt")) {
for (String pattern : patterns) {
writer.println(pattern);
}
} catch (IOException e) {
e.printStackTrace();
return;
}
List<Map<Character, Integer>> shiftTables = createShiftTables(patterns);
for (int i = 0; i < patterns.size(); i++) {
System.out.println("Shift table for pattern " + (i + 1) + ": " + shiftTables.get(i));
}
long startTimeBF = System.nanoTime();
for (String pattern : patterns) {
bruteForceSearch(text, pattern);
}
long endTimeBF = System.nanoTime();
long durationBF = (endTimeBF - startTimeBF) / numPatterns;
long startTimeHorspool = System.nanoTime();
for (String pattern : patterns) {
horspoolSearch(text, pattern, shiftTables.get(patterns.indexOf(pattern)));
}
long endTimeHorspool = System.nanoTime();
long durationHorspool = (endTimeHorspool - startTimeHorspool) / numPatterns;
System.out.println("Average running time of Brute Force: " + durationBF + " nanoseconds");
System.out.println("Average running time of Horspool: " + durationHorspool + " nanoseconds");
}
private static List<String> generateRandomPatterns(String text, int numPatterns, int patternLength) {
List<String> patterns = new ArrayList<>();
Random random = new Random();
int maxStartIndex = text.length() - patternLength;
for (int i = 0; i < numPatterns; i++) {
int startIndex = random.nextInt(maxStartIndex);
String pattern = text.substring(startIndex, startIndex + patternLength);
patterns.add(pattern);
}
return patterns;
}
private static List<Map<Character, Integer>> createShiftTables(List<String> patterns) {
List<Map<Character, Integer>> shiftTables = new ArrayList<>();
for (String pattern : patterns) {
Map<Character, Integer> shiftTable = new HashMap<>();
for (int i = 0; i < pattern.length() - 1; i++) {
shiftTable.put(pattern.charAt(i), pattern.length() - 1 - i);
}
shiftTables.add(shiftTable);
}
return shiftTables;
}
private static void bruteForceSearch(String text, String pattern) {
int n = text.length();
int m = pattern.length();
for (int i = 0; i <= n - m; i++) {
int j;
for (j = 0; j < m; j++) {
if (text.charAt(i + j) != pattern.charAt(j)) {
break;
}
}
if (j == m) {
}
}
}
private static void horspoolSearch(String text, String pattern, Map<Character, Integer> shiftTable) {
int n = text.length();
int m = pattern.length();
int i = 0;
while (i <= n - m) {
int j = m - 1;
while (j >= 0 && pattern.charAt(j) == text.charAt(i + j)) {
j--;
}
if (j < 0) {
i += shiftTable.getOrDefault(text.charAt(i + m - 1), m);
} else {
i += shiftTable.getOrDefault(text.charAt(i + j), m);
}
}
}
}