I have a problem that has been bothering me for a while now, it concerns the growth of loops in my program exponentially. I will let the code below do the talking and add comments within.
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; }
}
Output
a1 Test1
a1 Test2
b1 Test1
b1 Test2
c1 Test1
c1 Test2
a2 Test1
a2 Test2
b2 Test1
b2 Test2
c2 Test1
c2 Test2
a3 Test1
a3 Test2
b3 Test1
b3 Test2
c3 Test1
c3 Test2
As you can see the loops work and give me every possible combination of the supplied data.
My problem is the exponential growth of the for loops as i add more lists. There could be a large number of lists.
I do understand that the number of iterations will increase as the combinations are discovered, thats not a problem as i plan to programmatically limit the amount of iterations that can occur based on the users input after estimating the total iterations possible.
e.g. Total iterations would be 234 so only iterate 120 times ( 120 combinations )
The code provided works great with nested foreach loops but as it grows exponentially it becomes hard to read, hard to manage and generally unsightly.
I have looked at Permutation algorithms like these:
Algorithm to generate all possible permutations of a list?
Understanding Recursion to generate permutations.
But they only allow the use of one specific datatype and not multiple.
I also looked into cartesian product but again the only examples i have found refer to only a single data type.