C# 从单词列表生成长度不超过X的所有组合
如何从列表源生成一个包含一定长度的所有单词组合的列表 例如,我有一个10600多个单词的列表,我需要将其转换为一个列表,然而,子列表只需要包含一个给定最大长度的组合,例如,我将说3 我不在乎单词在子列表中出现的顺序。例如,我只需要列表中的以下一项:C# 从单词列表生成长度不超过X的所有组合,c#,asp.net,.net,C#,Asp.net,.net,如何从列表源生成一个包含一定长度的所有单词组合的列表 例如,我有一个10600多个单词的列表,我需要将其转换为一个列表,然而,子列表只需要包含一个给定最大长度的组合,例如,我将说3 我不在乎单词在子列表中出现的顺序。例如,我只需要列表中的以下一项: "laptop", "computer", "reviews" "laptop", "reviews", "computer" "computer", "laptop", "reviews" "computer" "reviews", "lapt
"laptop", "computer", "reviews"
"laptop", "reviews", "computer"
"computer", "laptop", "reviews"
"computer" "reviews", "laptop"
"reviews", "computer", "laptop"
"reviews", "laptop", "computer"
考虑到我需要生成的大量组合,这是否可能
非常感谢您的帮助。希望我没有弄乱任何事情
for(int i = 0; i < list.Count; i ++)
{
list1 = new List<string> { list[i] };
listcombinations.Add(list1);
for(int j = i + 1; j < list.Count; j ++)
{
list1 = new List<string> { list[i], list[j] };
listcombinations.Add(list1);
for(int k = j + 1; k < list.Count; k ++)
{
list1 = new List<string> { list[i], list[j], list[k] };
listcombinations.Add(list1);
}
}
}
希望我没有搞砸任何事
for(int i = 0; i < list.Count; i ++)
{
list1 = new List<string> { list[i] };
listcombinations.Add(list1);
for(int j = i + 1; j < list.Count; j ++)
{
list1 = new List<string> { list[i], list[j] };
listcombinations.Add(list1);
for(int k = j + 1; k < list.Count; k ++)
{
list1 = new List<string> { list[i], list[j], list[k] };
listcombinations.Add(list1);
}
}
}
我想问题主要在于检查列表中是否已经存在单词组合:
"laptop", "computer", "reviews"
"laptop", "reviews", "computer"
"computer", "laptop", "reviews"
"computer" "reviews", "laptop"
"reviews", "computer", "laptop"
"reviews", "laptop", "computer"
您可以为此做些什么:
//generate a dictionary with key hashcode / value list of string
Dictionary<int, List<string>> validCombinations= new Dictionary<int, List<string>>();
//generating anyway your combinations (looping through the words)
List<string> combinationToCheck = new List<string>(){"reviews", "laptop", "computer"};
//sort the words
combinationToCheck.Sort();
string combined = String.Join("", combinationToCheck.ToArray());
//calculate a hash
int hashCode = combined.GetHashCode();
//add the combination if the same hash doesnt exist yet
if(!validCombinations.ContainsKey(hashCode))
validCombinations.Add(hashCode, combinationToCheck);
我想问题主要在于检查列表中是否已经存在单词组合:
"laptop", "computer", "reviews"
"laptop", "reviews", "computer"
"computer", "laptop", "reviews"
"computer" "reviews", "laptop"
"reviews", "computer", "laptop"
"reviews", "laptop", "computer"
您可以为此做些什么:
//generate a dictionary with key hashcode / value list of string
Dictionary<int, List<string>> validCombinations= new Dictionary<int, List<string>>();
//generating anyway your combinations (looping through the words)
List<string> combinationToCheck = new List<string>(){"reviews", "laptop", "computer"};
//sort the words
combinationToCheck.Sort();
string combined = String.Join("", combinationToCheck.ToArray());
//calculate a hash
int hashCode = combined.GetHashCode();
//add the combination if the same hash doesnt exist yet
if(!validCombinations.ContainsKey(hashCode))
validCombinations.Add(hashCode, combinationToCheck);
首先,我不确定您是否真的想要生成如此庞大的列表。如果你真的这么做了,那么我建议你考虑使用懒惰列表生成来代替这个巨大的列表:
static void Main()
{
var words = new List<string> {"w1", "w2", "w3", "w4", "w5", "w6", "w7"};
foreach (var list in Generate(words, 3))
{
Console.WriteLine(string.Join(", ", list));
}
}
static IEnumerable<List<string>> Generate(List<string> words, int length, int ix = 0, int[] indexes = null)
{
indexes = indexes ?? Enumerable.Range(0, length).ToArray();
if (ix > 0)
yield return indexes.Take(ix).Select(x => words[x]).ToList();
if (ix > length)
yield break;
if (ix == length)
{
yield return indexes.Select(x => words[x]).ToList();
}
else
{
for (int jx = ix > 0 ? indexes[ix-1]+1 : 0; jx < words.Count; jx++)
{
indexes[ix] = jx;
foreach (var list in Generate(words, length, ix + 1, indexes))
yield return list;
}
}
}
首先,我不确定您是否真的想要生成如此庞大的列表。如果你真的这么做了,那么我建议你考虑使用懒惰列表生成来代替这个巨大的列表:
static void Main()
{
var words = new List<string> {"w1", "w2", "w3", "w4", "w5", "w6", "w7"};
foreach (var list in Generate(words, 3))
{
Console.WriteLine(string.Join(", ", list));
}
}
static IEnumerable<List<string>> Generate(List<string> words, int length, int ix = 0, int[] indexes = null)
{
indexes = indexes ?? Enumerable.Range(0, length).ToArray();
if (ix > 0)
yield return indexes.Take(ix).Select(x => words[x]).ToList();
if (ix > length)
yield break;
if (ix == length)
{
yield return indexes.Select(x => words[x]).ToList();
}
else
{
for (int jx = ix > 0 ? indexes[ix-1]+1 : 0; jx < words.Count; jx++)
{
indexes[ix] = jx;
foreach (var list in Generate(words, length, ix + 1, indexes))
yield return list;
}
}
}
那么长度为3的列表中的每个不同组合?这不是1.98446490 x 10^11组合吗?我还没有计算长度为1和2的组合,这是你想要的。你打算对最后的列表做什么?那么从长度为3的列表中的每个不同组合?这不是1.98446490 x 10^11组合吗?我还没有计算长度为1和2的组合,这是你想要的。你打算如何处理最终列表?这只适用于长度为3的列表。但这只是原始问题中的一个例子。如果需要生成10个元素的列表,该怎么办?这样的解决方案看起来会非常古怪。@OleksandrPshenychnyy原始问题没有提到,例如,它是后来编辑的。对于这种情况,我的解决方案简单易懂,并且没有任何性能开销。无论如何,将其转换为使用递归是非常简单的。这只适用于长度为3的列表。但这只是原始问题中的一个例子。如果需要生成10个元素的列表,该怎么办?这样的解决方案看起来会非常古怪。@OleksandrPshenychnyy原始问题没有提到,例如,它是后来编辑的。对于这种情况,我的解决方案简单易懂,并且没有任何性能开销。无论如何,将其转换为使用递归非常简单。感谢您的响应,它似乎工作得很好。在笔记本电脑、电脑、评论这三个词上进行测试,这给了我第二次出现笔记本电脑评论。在删除if ix==length语句之后,它工作得很好。谢谢感谢您的回复,它似乎工作得很好。在笔记本电脑、电脑、评论这三个词上进行测试,这给了我第二次出现笔记本电脑评论。在删除if ix==length语句之后,它工作得很好。谢谢