从三个 List<String> 中生成并输出所有可能的组合,每个唯一项仅一次

generate and output all possible combinations, from three List<String> only once per unique item

我正在尝试生成所有可能的句子组合。作为变量,我有两个字符串,一个字符串将是主题,例如health 并且一个将是一个对象,例如 fruit,但是我将有一个 List<String> 值与一个 "head" 词相关联,因此与两个组件保持一致刚才提到,它们将与列表 [improve, change, alter, modify] 相关联。我想生成这些句子的所有可能组合,并将每个句子添加到 List<Sentences> 中,例如:

Sentence example_sentence = new Sentence(verb, object, subject);
sentences.add(example_sentence);

现在发生这种情况的较大函数如下所示:

public Sentence dataPreprocessing(String raw_subject, String raw_object, String raw_verb, List<Sentence> sentences) throws IOException {
    WordNet wordnet = new WordNet();
    String verb = wordnet.getStem(raw_verb);
    String object = wordnet.getStem(raw_object);        
    String subject = wordnet.getStem(raw_subject);
    List<String> verb_hypernym_container = new ArrayList<>();       
    verb_hypernym_container = wordnet.getHypernyms(verb, POS.VERB);
    //wordnet.getHypernyms(this.object, POS.NOUN);  
    //wordnet.getHypernyms(this.subject, POS.NOUN); 
    Sentence return_sentence = new Sentence( verb, object, subject );
    return return_sentence;
}

我怎样才能最有效地实现生成所有可能句子的目标?

因为你有固定数量的列表,最简单的方法就是使用嵌套循环:

List<Sentence> sentences = new ArrayList<>();

for(String verb_hypernym : wordnet.getHypernyms(verb, POS.VERB))
    for(String object_hypernym : wordnet.getHypernyms(object, POS.NOUN))
        for(String subject_hypernym : wordnet.getHypernyms(subject, POS.NOUN))
            sentences.add(new Sentence(verb_hypernym, object_hypernym, subject_hypernym));

return sentences;

或者,为了避免不必要地更频繁地调用 getHypernyms

List<String> verb_hypernyms = wordnet.getHypernyms(verb, POS.VERB);
List<String> object_hypernyms = wordnet.getHypernyms(object, POS.NOUN);
List<String> subject_hypernyms = wordnet.getHypernyms(subject, POS.NOUN);


for(String verb_hypernym : verb_hypernyms)
    for(String object_hypernym : object_hypernyms)
        for(String subject_hypernym : subject_hypernyms)
            sentences.add(new Sentence(verb_hypernym, object_hypernym, subject_hypernym));

return sentences;

获得名词和动词列表后,您可以使用流来 return 句子列表。这也让您有机会删除任何重复项、排序或您需要对流执行的任何其他操作。

List<Sentence> sentences = subjectList.stream()
        .flatMap(object -> verbList.stream()
            .flatMap(verb -> objectList.stream()
                .map(subject -> new Sentence(object, verb, subject))))
        .distinct()
        .collect(Collectors.toList());