获取特定字符串之后的所有不同单词

Getting all the distinct words that follow after a specific string

我想知道“apple”后面所有不同的词。我正在使用 HashSet 来获取这些词,但我 运行 出错了。

这是我在main中调用的方法。我应该得到 [banana, cherry] 作为 return 值,但我只得到 [banana].

ArrayList<String> test = new ArrayList<>();
        test.add("orange");
        test.add("apple");
        test.add("banana");
        test.add("cherry");
        System.out.println(test);
        System.out.println(problem1(test));

public static HashSet<String> problem1 (ArrayList<String> allWords){
        HashSet<String> words = new HashSet<>();
        String previousWord = "";
        
        for(String currentWord : allWords)
        {
            if(previousWord.equals("apple")) {
                words.add(currentWord);
                
            }
            previousWord = currentWord;
        }
        return words;
    }

previousWord 的“cherry”不是“apple”,所以如果函数不是 return“cherry”也是正常的

您实际上可以将问题简化为以下步骤:

  1. 找到关键字的索引(这里是“apple”)
  2. 添加从这个索引 + 1(下一个词)到输入结束的所有内容
public static Set<String> problem1 (List<String> allWords){
    HashSet<String> words = new HashSet<>();
    int startIndex = allWords.indexOf("apple");
    if (startIndex == -1) {
        return words; // No match
    }
    for (int i = startIndex + 1; i < allWords.size(); i++) {
        words.add(allWords.get(i));
    }
    return words;
}

这个任务可以通过以下方法解决:

  • List::indexOf - 找到所需字符串的索引并增加它以跳过所需的字符串
  • List::subList - 从所需的索引中获取子列表

此外,将结果作为 LinkedHashSet 来维护输入列表中元素的顺序可能会更好:

public static Set<String> findWordsAfter(List<String> allWords, String afterMe) {
    
    return new LinkedHashSet<>(
        allWords.subList(allWords.indexOf(afterMe) + 1, allWords.size())
    );
}

类似地,Stream API 可用于跳过输入列表中的单词并将结果收集到一个集合中:

public static Set<String> findWordsAfter2(List<String> allWords, String wordAfter) {  
    return allWords.stream()
            .skip(allWords.indexOf(wordAfter) + 1)
            .collect(Collectors.toCollection(LinkedHashSet::new));
}

测试:

List<String> words = Arrays.asList("orange", "apple", "banana", "cherry", "cherry");

List<String> lookFor = Arrays.asList("apple", "pear");

lookFor.forEach(wordAfter -> {
    System.out.printf("Getting words after '%s'%n", wordAfter);
    
    System.out.println("subList:     " + findWordsAfter(words, wordAfter));
    System.out.println("stream.skip: " + findWordsAfter2(words, wordAfter));
    
    System.out.println("----");
});

输出

Getting words after 'apple'
subList:     [banana, cherry]
stream.skip: [banana, cherry]
----
Getting words after 'pear'
subList:     [orange, apple, banana, cherry]
stream.skip: [orange, apple, banana, cherry]
----