我正在嘗試使用List<string>. 例如,如果我想生成 2 的所有可能的單詞組合,該函式將如下所示:
public static List<string> GenerateWordsOf2(List<string> uniqueWords)
{
List<string> unique2Words = new();
for (int i = 0; i < uniqueWords.Count; i )
{
for (int j = 0; j < uniqueWords.Count; j )
{
if (i != j)
{
unique2Words.Add(uniqueWords[i] " " uniqueWords[j]);
}
}
}
return unique2Words;
}
這可以按預期作業,但是當我想生成例如 3 的唯一單詞時,我需要為此撰寫一個新函式,在其中創建另一個回圈。是否有一種更有效的方法來做到這一點,比如制作一個函式來獲取一個數字并生成那么多獨特的單詞串列?
uj5u.com熱心網友回復:
您可以使用單個 for 回圈迭代地執行此操作,如下所示。
- 從僅包含“空句子”的串列開始。
- 在每個步驟中,將每個單詞添加到每個先前構建的句子中。
假設uniqueWords是“a”、“b”、“c”。
- 一開始,您將擁有 {""}。
- 第一步后,您將擁有 {"a", "b", "c"}
- 第二步之后,你會得到 { "a a", "a b", "a c", "b a", "b b", "b c", "c a" , "c b", "c c"}
- 第三步之后,你會得到 { "a a a", "a b a", ... }
唯一需要的修改是過濾掉重復項。這導致了這樣的(未優化)示例:
使用系統;使用 System.Collections.Generic;
public class SentenceGenerator
{
public static List<List<string>> ExpandSentences(List<List<string>> partialSentences, List<string> uniqueWords)
{
var newSentences = new List<List<string>>();
foreach(var sentence in partialSentences)
{
foreach(var word in uniqueWords)
{
if(sentence.Contains(word))
{
continue;
}
// Make a copy of the old sentence
var newSentence = new List<string>(sentence);
// Add a new word
newSentence.Add(word);
newSentences.Add(newSentence);
}
}
return newSentences;
}
public static void Main()
{
var uniqueWords = new List<string>() {
"hello",
"beautiful",
"world",
"full",
"of",
"people" };
var sentences = new List<List<string>>() {
// Start with an empty sentence
new List<string>()
};
for(int i = 1; i <= 3; i )
{
sentences = ExpandSentences(sentences, uniqueWords);
}
System.Console.WriteLine("Generated " sentences.Count " sentences.");
foreach(var sentence in sentences)
{
System.Console.WriteLine(string.Join(" ", sentence));
}
}
}
在線運行 (IDEOne)
uj5u.com熱心網友回復:
例如,如果您想獲取所有3專案組合,則可以將陣列保留indexes在可以放置要獲取的專案的位置:
uniqueWords = {'A', 'B', 'C', 'D'}
indexes = {0, 0, 0} // AAA
indexes = {0, 0, 1} // AAB
indexes = {0, 0, 2} // AAC
indexes = {0, 1, 0} // ABA
...
indexes = {2, 2, 2} // CCC
代碼:(讓我們在一般情況下實作它,IEnumerable<T>作為輸入引數)
using System.Linq;
...
private static IEnumerable<T[]> AllWords<T>(IEnumerable<T> uniqueWords, int count) {
T[] words = uniqueWords.ToArray();
int[] indexes = new int[count];
do {
yield return indexes.Select(index => words[index]).ToArray();
for (int i = indexes.Length - 1; i >= 0; --i)
if ( indexes[i] >= words.Length)
indexes[i] = 0;
else
break;
}
while (!indexes.All(index => index == 0));
}
演示:
List<char> demo = new List<char>() { 'A', 'B', 'C', 'D' };
int count = 2;
var result = string.Join(Environment.NewLine, AllWords(demo, count)
.Select(array => string.Join(" ", array)));
Console.Write(result);
輸出:
A A
A B
A C
A D
B A
B B
B C
B D
C A
C B
C C
C D
D A
D B
D C
D D
編輯:如果希望所有生成的單詞都是唯一的,即要排除A A等,B B您可以添加Where:
List<char> demo = new List<char>() { 'A', 'B', 'C', 'D' };
int count = 2;
var result = string.Join(Environment.NewLine, AllWords(demo, count)
.Where(array => array.Distinct().Count() == count)
.Select(array => string.Join(" ", array)));
Console.Write(result);
或稍作修改修改AllWords:
private static IEnumerable<T[]> AllWords<T>(IEnumerable<T> uniqueWords, int count) {
T[] words = uniqueWords.ToArray();
int[] indexes = new int[count];
HashSet<int> unique = new();
do {
unique.Clear();
foreach (int item in indexes)
unique.Add(item);
if (unique.Count == indexes.Length)
yield return indexes.Select(index => words[index]).ToArray();
for (int i = indexes.Length - 1; i >= 0; --i)
if ( indexes[i] >= words.Length)
indexes[i] = 0;
else
break;
}
while (!indexes.All(index => index == 0));
}
輸出:
A B
A C
A D
B A
B C
B D
C A
C B
C D
D A
D B
D C
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/492021.html
