Как сгенерировать комбинацию из N элементов с ограниченным запасом по 2 без явных вложенных циклов

Если N фиксировано, например N = 3, то это легко, я могу использовать вложенные циклы глубины 3. например.

from i in Enumerable.Range(0, 2)
from j in Enumerable.Range(0, 2)
from k in Enumerable.Range(0, 2)
select new int[] { i, j, k };

а если N переменная?


person colinfang    schedule 02.11.2011    source источник
comment
Дубликат: stackoverflow.com/q/3428870/21727   -  person mbeckish    schedule 02.11.2011
comment
Что мне не нравится, так это то, что вы получаете массив переменной размерности. Ты действительно уверен, что хочешь этого?   -  person Tipx    schedule 02.11.2011
comment
@Tipx - я думаю, что цель состоит в том, чтобы создать коллекцию массивов из N элементов, что и делает пример.   -  person mbeckish    schedule 02.11.2011
comment
возможный дубликат декартово произведение нескольких массивов   -  person Saeed Amiri    schedule 02.11.2011


Ответы (1)


Что вам нужно, так это своего рода «множитель» массива. Что-то вроде этого:

private static IEnumerable<int[]> Multiply(IEnumerable<int[]> input,
    IEnumerable<int> multiplyers)
{
    foreach (var array in input)
    {
        foreach (var multiplyer in multiplyers)
        {
            yield return array.Concat(new int[] { multiplyer })
                .ToArray();
        }
    }
}

Вы можете использовать этот метод следующим образом, чтобы получить тот же результат, что и в приведенном выше примере:

int n = 3;

var multiplyers = Enumerable.Range(0, 2);

IEnumerable<int[]> results = 
    from m in multiplyers select new int[] { m };

while (n-- > 1)
{
    results = Multiply(results, multiplyers);
}

Теперь n является переменной.

person Steven    schedule 02.11.2011