【发布时间】:2015-07-27 14:51:47
【问题描述】:
我有一个问题困扰了我一段时间,它与我的程序中循环的成倍增长有关。我将让下面的代码进行对话并在其中添加 cmets。
void Main()
{
//Here we are just creating simple lists
List<string> strings = new List<string>();
strings.Add("a");
strings.Add("b");
strings.Add("c");
List<int> integers = new List<int>();
integers.Add(1);
integers.Add(2);
integers.Add(3);
//Creating complex classes ( not really )
ComplexClass cc1 = new ComplexClass();
cc1.CCString = "A test";
cc1.CCInt = 2;
ComplexClass cc2 = new ComplexClass();
cc2.CCString = "Another test";
cc2.CCInt = 6;
//Creating a list of these too
List< ComplexClass > complexClasses = new List< ComplexClass >();
complexClasses.Add(cc1);
complexClasses.Add(cc2);
//Here i want to create every possible combination using each of the lists
//and then add these to a testData class to do other things with, serialize, save, print etc.
//The main question is here, the for loops will definitely increase exponentially with each
//list added to.
foreach( int i in integers )
{
foreach( string s in strings )
{
foreach( ComplexClass compClass in complexClasses )
{
TestData data = new TestData();
data.TestInteger = i;
data.TestString = s;
data.TestComplexClass = compClass;
OutPutTestData( data );
}
}
}
}
//Simply outputs the data as test but I will be keeping the object for later also
public void OutPutTestData( TestData testData )
{
Console.WriteLine( testData.TestString + testData.TestInteger + testData.TestComplexClass.CCString );
}
//The "Complex class" again not that complex but an example of what im tring to achieve
public class ComplexClass
{
public string CCString{ get; set; }
public int CCInt { get; set; }
}
//The overall test object which holds multiple properties of different data types
public class TestData
{
public string TestString { get; set; }
public int TestInteger { get; set; }
public ComplexClass TestComplexClass { get; set; }
}
输出
a1 测试1
a1 测试2
b1 测试1
b1 测试2
c1 测试1
c1 测试2
a2 测试1
a2 测试2
b2 测试1
b2 测试2
c2 测试1
c2 测试2
a3 测试1
a3 测试2
b3 测试1
b3 测试2
c3 测试1
c3 测试2
如您所见,循环有效,并为我提供了所提供数据的所有可能组合。
我的问题是随着我添加更多列表,for 循环呈指数增长。可能有大量列表。
我知道迭代次数会随着组合的发现而增加,这不是问题,因为我计划在估计可能的总迭代次数后,根据用户输入以编程方式限制可能发生的迭代次数。
例如总迭代次数为 234,因此仅迭代 120 次(120 种组合)
提供的代码非常适合嵌套的 foreach 循环,但随着它呈指数增长,它变得难以阅读、难以管理并且通常不美观。
我看过这样的置换算法:
Algorithm to generate all possible permutations of a list?
Understanding Recursion to generate permutations.
但它们只允许使用一种特定的数据类型而不是多种。
我还研究了笛卡尔积,但我发现的唯一示例仅涉及一种数据类型。
【问题讨论】:
-
最终游戏到底是什么?找到
Lists的每一个可能的组合? -
我想我不确定问题到底是什么。无论你做什么,组合的数量都会成倍增长,除非我错过了什么。
-
@Servy 你愿意提供一个你认为应该如何工作的解决方案吗?
-
你看LINQ and N-ary Cartesian Products 和后续行动了吗?
-
@Servy 您提出的解决方案将添加两个强制转换并且仍然需要额外的代码来维护,但如果您对此有强烈的感觉,请继续。我不会重新打开它。