【问题标题】:Getting all the distinct words that follow after a specific string获取特定字符串之后的所有不同单词
【发布时间】:2021-07-02 13:11:17
【问题描述】:

我想知道“apple”之后的所有不同单词。我正在使用 HashSet 来获取这些单词,但我遇到了错误。

这是我在 main 中调用的方法。我应该得到 [banana, cherry] 作为返回值,但我只得到 [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;
    }

【问题讨论】:

  • '遇到错误',这是模糊的。你能说得更具体些吗
  • 嘿,你有机会看到我剩下的问题吗?
  • 用调试器单步调试你的程序。
  • 为什么你认为你应该得到香蕉和樱桃?只有一个紧随在苹果之后立即(那是香蕉)。樱桃紧随香蕉之后,所以它似乎不符合你的标准。
  • @OHGODSPIDERS 感谢您的帮助!我将该行代码包装在一个 else 块中,我得到了预期的输出。这是一种有效的做法还是应该将语句放在 if 块中?

标签: java arraylist hashset


【解决方案1】:

可以借助以下方法解决此任务:

  • 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]
----

【讨论】:

    【解决方案2】:

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

    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;
    }
    

    【讨论】:

      【解决方案3】:

      previous“cherry”的单词不是“apple”,所以函数没有返回“cherry”是正常的

      【讨论】:

        猜你喜欢
        • 2019-04-22
        • 2014-10-03
        • 2018-08-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-08-02
        • 2018-09-30
        相关资源
        最近更新 更多