3
\$\begingroup\$

In response to a recent SO question, I answered with the following code, and was wondering if anyone had any input on it. I'm always looking for an opprotunity to learn!

import java.util.HashMap;
import java.util.Map;
import java.util.Stack;

public class WordFinder {

    public static void main(String[] args) {
        String phrase = "0123hello9012hello8901hello7890";
        String[] words = { "hello", "90" };

        Map<String, Stack<Integer>> dest = findWordsInString(words, phrase);

        System.out.println(dest.toString());
    }

    public static Map<String, Stack<Integer>> findWordsInString(String[] words, String phrase) {
        Map<String, Stack<Integer>> dest = new HashMap<>();

        for (String word : words) {
            Stack<Integer> locations = new Stack<>();

            for (int loc = -1; (loc = phrase.indexOf(word, loc + 1)) != -1;) {
                locations.add(loc);
            }

            dest.put(word, locations);
        }

        return dest;
    }
}

Program Output:

{90=[9, 19, 29], hello=[4, 13, 22]}
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

Map<String, Stack<Integer>> dest = findWordsInString(words, phrase);

I don't see the need at all for a Stack here. And not a Map either.

Let's say that you would want to find the third occourance of the word, and then randomly the first, and the fifth, and the second... Then you would want to store the indices in a List, not a Stack.

And why deal with multiple words at the same time? The way that your method is written, it makes more sense to search for all occurances of one word at a time.

As for the very important for loop, while it is totally alright to write it like that, I would personally prefer a while loop with something like this: (there is a bunch of variations for how you could do this)

int loc = phrase.indexOf(word);
while (loc != -1) {
   locations.add(loc);
   loc = phrase.indexOf(word, loc + 1);
}

It makes it easier to read the code, in my opinion.

\$\endgroup\$
2
  • \$\begingroup\$ What would an implementation that doesn't use maps or stacks look like? I did think about that list case; I wanted to include it but thought that the data structure might be a bit "heavy." As for your third point, isn't that what my code does? I loop over and record an entry in the map for each word and its occurrences. Thanks for the input! \$\endgroup\$
    – T145
    Sep 6, 2016 at 20:46
  • \$\begingroup\$ @T145 You could wrap the results from an inner method to a map and return that if you'd like. I'm just missing the method header List<Integer> findIndicesOfWord(String sentence, String word). Yes, your code is doing the same as my while loop but your code uses the - in my opinion very long - line for (int loc = -1; (loc = phrase.indexOf(word, loc + 1)) != -1;) { \$\endgroup\$ Sep 6, 2016 at 21:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.