KoopaM
KoopaM

Reputation: 50

Dictionary input file and string manipulation

I am writing a program that searches a file imported for a string of characters and length user enters. For example, "Enter the possible letters in your word: " Keyboard scans "aeppr" "Enter the number of letters in your target words:" "5"

and then proceeds to search my dictionary file and ultimately prints: 1 paper

I was wondering if you can use indexOf or any other methods or classes to display this result. As of now my code only displays words that match the searched letters and length exactly. Any help or advice would be greatly appreciated.

    String input;
    String altInput;

    Scanner inFile = new Scanner(new File("words.txt"));
    Scanner scanner = new Scanner(System.in);

    String lettersBeingTested;
    int numberOfLetters;

    System.out.println("Enter the possible letters in your word: ");
    lettersBeingTested = scanner.next();
    System.out.println("Enter the number of letters in your target words: ");
    numberOfLetters = scanner.nextInt();
    int count = 0;
    while (inFile.hasNext()) {

        input = inFile.next();
        altInput = "";

        for (int i = 0; i < input.length(); i++) {

            altInput = altInput + input.charAt(i);

            if (input.contains(lettersBeingTested) && altInput.length() == numberOfLetters) {

                count++;
                System.out.println(count + " " + altInput);

            }
        }
    }
    System.out.println("End of list: " + count + " words found");

    inFile.close();
}

Upvotes: 1

Views: 94

Answers (1)

Oleg Cherednik
Oleg Cherednik

Reputation: 18245

public static void main(String[] args) throws FileNotFoundException {
    findWords(new File("words.txt"));
}

public static void findWords(File file) throws FileNotFoundException {
    try (Scanner scan = new Scanner(System.in)) {
        System.out.println("Enter the possible letters in your word: ");
        String lettersBeingTested = scan.next();
        System.out.println("Enter the number of letters in your target words: ");
        int numberOfLetters = scan.nextInt();
        int[] requiredHistogram = histogram(lettersBeingTested, new int[26]);

        Predicate<int[]> predicate = wordHistogram -> {
            for (int i = 0; i < requiredHistogram.length; i++)
                if (requiredHistogram[i] > 0 && wordHistogram[i] < requiredHistogram[i])
                    return false;
            return true;
        };

        Set<String> words = findWords(file, predicate, numberOfLetters);
        int i = 1;

        for (String word : words)
            System.out.println(i + " " + word);

        System.out.println("End of list: " + words.size() + " words found");
    }
}

private static int[] histogram(String str, int[] histogram) {
    Arrays.fill(histogram, 0);
    str = str.toLowerCase();

    for (int i = 0; i < str.length(); i++)
        histogram[str.charAt(i) - 'a']++;

    return histogram;
}

private static Set<String> findWords(File file, Predicate<int[]> predicate, int numberOfLetters) throws FileNotFoundException {
    try (Scanner scan = new Scanner(file)) {
        Set<String> words = new LinkedHashSet<>();
        int[] histogram = new int[26];

        while (scan.hasNext()) {
            String word = scan.next().toLowerCase();

            if (word.length() == numberOfLetters && predicate.test(histogram(word, histogram)))
                words.add(word);
        }

        return words;
    }
}

This look a bit complicated using histogramm. I think that if lettersBeingTested = "aa", then you're looking for words with at lest 2 'a' in it. Threfore, you have to build a histogram and compare symbol appearance number in the current words and in example one.

P.S.

altInput = altInput + input.charAt(i);

String concatenation within loop flows bad performance. Do look at StringBuilder isntead.

Upvotes: 1

Related Questions