Algorithm to represent a sequence of numbers

I have a sequence of numbers to generate, and I want to generate it using some sort of algorithm (iterative or recursive, doesn't matter).

Contextualizing: This numbers are indexes to iterative over a list of lists. I need to do a permutation (combination, i don't know exactly), but I need to generate all combinations of all positions of that list of lists.

The sequence and the output I am trying to get is:

1 1
2 1
3 1
4 1
5 1

1 2
2 1
3 1
4 1
5 1

1 3
2 1
3 1
4 1
5 1

1 4
2 1
3 1
4 1
5 1

1 5
2 1
3 1
4 1
5 1

1 1
2 2
3 1
4 1
5 1

1 2
2 2
3 1
4 1
5 1

1 3
2 2
3 1
4 1
5 1

1 4
2 2
3 1
4 1
5 1

1 5
2 2
3 1
4 1
5 1

1 1
2 3
3 1
4 1
5 1

1 2
2 3
3 1
4 1
5 1

1 3
2 3
3 1
4 1
5 1

1 4
2 3
3 1
4 1
5 1

1 5
2 3
3 1
4 1
5 1

1 1
2 4
3 1
4 1
5 1

and so on... the last state is:

1 5
2 5
3 5
4 5
5 5

Note that at each line break is a step of iteration or recursion. The algorithm must be generic. This code that i wrote can help, but it isn't what I want. :(

List<List<int>> lstDays = new List<List<int>>
{
    new List<int>{1,2,3,4,5}, //day 18
    new List<int>{1,2,3,4,5}, //day 19
    new List<int>{1,2,3,4,5}, //day 22
    new List<int>{1,2,3,4,5}, //day 23
    new List<int>{1,2,3,4,5}, //day 24
};

for(int i=0;i<lstDays.Count;i++)
{
    for(int j=0;j<lstDays[i].Count;j++)
    {
        for(int k=0;k<lstDays.Count;k++)
        {
            Console.Write(k+1);

            //Console.Write(j+1);

            Console.Write('n');
        }
        Console.Write('n');
    }
}

I hope that you can help me ! (:


Based on comments below by the venerable Eric Lippert, edits for the OPs original intent:

public void OutputSequence(int length){
    Recurse(length-1, Enumerable.Range(1, length).ToArray(), new int[length]);  
}

public void Recurse(int position, int[] arr, int[] state){  
    if (position == -1){
        PrintState(state);  
        return;
    }

    for (int i = 0; i < arr.Length; i++)
    {           
        state[position] = arr[i];
        Recurse(position-1, arr, state);
    }
}

public void PrintState(int[] state){
    for (int i = 0; i < state.Length; i++)
        Console.WriteLine ("{0} {1}",i+1, state[i]);        

        Console.WriteLine ();
}

OutputSequence(5); will give the output the OP originally asked for.

Old Answer

What you're looking for is called a Cartesian Product. LINQ is your friend:

var pairs = from i in Enumerable.Range(1, 5)
            from j in Enumerable.Range(1, 5)
            select new {i, j};

foreach(var p in pairs)
    Console.WriteLine ("{0} {1}", p.i, p.j);

EDIT: Just for fun, here's a way to do N-Ary cartesian products.

public IEnumerable<IEnumerable<int>> NAryCartesianProduct(int upper, int times){
    if (times == 0)
        return Enumerable.Empty<IEnumerable<int>>();

    var nums = Enumerable.Range(1, upper);          
    IEnumerable<IEnumerable<int>> products = nums.Select(i => new[]{i});

    for (int i = 1; i < times; i++)
    {
        products = from p in products
                   from n in nums
                   select p.Concat(new [] {n});                                     
    }       

    return products;
}

And now you can get what you had before with:

var p = NAryCartesianProduct(5, 2);

foreach(var i in p)
    Console.WriteLine (i);

I'm sure there's a more efficient way than creating new arrays all of the time but I just hacked this up quick :)

Here's a much more informative answer on this: Generating all Possible Combinations

EDIT2: Apparently the original link is the origination of the answer from that SO post. I didn't read through to the end until now.


You can do it like this:

int[] second = new[] {0,0,0,0,0};
bool finish = false;
while (true) {
    for (int i = 0 ; i != 5 ; i++) {
        Console.WriteLine("{0} {1}", i+1, second[i]+1);
    }
    Console.WriteLine();
    int p = 0;
    do {
        second[p]++;
        if (second[p] == 5) {
            second[p] = 0;
            p++;
        } else {
            break;
        }
    } while (p != 5);
    if (p == 5) break;
}

The sequence of the second digits is stored in the array "creatively" named second . The do / while loop "increments" this array as if it were a base-5 number stored as five separate digits.

Here is a demo on ideone.

链接地址: http://www.djcxy.com/p/6364.html

上一篇: 从两个值生成唯一的ID

下一篇: 算法来表示一个数字序列