我有一个这种类型列表>包含这个
List<int> A = new List<int> {1, 2, 3, 4, 5};
List<int> B = new List<int> {0, 1};
List<int> C = new List<int> {6};
List<int> X = new List<int> {....,....};
我希望拥有像这样的所有组合
1-0-6
1-1-6
2-0-6
2-1-6
3-0-6
等等。
根据你的意思,这可以解决使用Linq?
答案 0 :(得分:37)
这与我提出的另一个问题的this answer非常相似:
var combinations = from a in A
from b in B
from c in C
orderby a, b, c
select new List<int> { a, b, c };
var x = combinations.ToList();
对于可变数量的输入,现在添加了泛型:
var x = AllCombinationsOf(A, B, C);
public static List<List<T>> AllCombinationsOf<T>(params List<T>[] sets)
{
// need array bounds checking etc for production
var combinations = new List<List<T>>();
// prime the data
foreach (var value in sets[0])
combinations.Add(new List<T> { value });
foreach (var set in sets.Skip(1))
combinations = AddExtraSet(combinations, set);
return combinations;
}
private static List<List<T>> AddExtraSet<T>
(List<List<T>> combinations, List<T> set)
{
var newCombinations = from value in set
from combination in combinations
select new List<T>(combination) { value };
return newCombinations.ToList();
}
答案 1 :(得分:14)
如果维度数量是固定的,则只需SelectMany
:
var qry = from a in A
from b in B
from c in C
select new {A=a,B=b,C=c};
但是,如果维度由数据控制,则需要使用递归:
static void Main() {
List<List<int>> outerList = new List<List<int>>
{ new List<int>(){1, 2, 3, 4, 5},
new List<int>(){0, 1},
new List<int>(){6,3},
new List<int>(){1,3,5}
};
int[] result = new int[outerList.Count];
Recurse(result, 0, outerList);
}
static void Recurse<TList>(int[] selected, int index,
IEnumerable<TList> remaining) where TList : IEnumerable<int> {
IEnumerable<int> nextList = remaining.FirstOrDefault();
if (nextList == null) {
StringBuilder sb = new StringBuilder();
foreach (int i in selected) {
sb.Append(i).Append(',');
}
if (sb.Length > 0) sb.Length--;
Console.WriteLine(sb);
} else {
foreach (int i in nextList) {
selected[index] = i;
Recurse(selected, index + 1, remaining.Skip(1));
}
}
}
答案 2 :(得分:8)
如何使用.Join方法生成组合的方法?
static void Main()
{
List<List<int>> collectionOfSeries = new List<List<int>>
{ new List<int>(){1, 2, 3, 4, 5},
new List<int>(){0, 1},
new List<int>(){6,3},
new List<int>(){1,3,5}
};
int[] result = new int[collectionOfSeries.Count];
List<List<int>> combinations = GenerateCombinations(collectionOfSeries);
Display(combinations);
}
此方法 GenerateCombinations(..)执行生成组合的主要工作。 此方法是通用的,因此可用于生成任何类型的组合。
private static List<List<T>> GenerateCombinations<T>(
List<List<T>> collectionOfSeries)
{
List<List<T>> generatedCombinations =
collectionOfSeries.Take(1)
.FirstOrDefault()
.Select(i => (new T[]{i}).ToList())
.ToList();
foreach (List<T> series in collectionOfSeries.Skip(1))
{
generatedCombinations =
generatedCombinations
.Join(series as List<T>,
combination => true,
i => true,
(combination, i) =>
{
List<T> nextLevelCombination =
new List<T>(combination);
nextLevelCombination.Add(i);
return nextLevelCombination;
}).ToList();
}
return generatedCombinations;
}
显示助手..
private static void Display<T>(List<List<T>> generatedCombinations)
{
int index = 0;
foreach (var generatedCombination in generatedCombinations)
{
Console.Write("{0}\t:", ++index);
foreach (var i in generatedCombination)
{
Console.Write("{0,3}", i);
}
Console.WriteLine();
}
Console.ReadKey();
}
答案 3 :(得分:2)
//Done in 2 while loops. No recursion required
#include<stdio.h>
#define MAX 100
typedef struct list
{
int elements[MAX];
}list;
list n[10];
int number,count[10],temp[10];
void print();
int main()
{
int i,j,mult=1,mult_count;
printf("Enter the number of lists - ");
scanf("%d",&number);
for(i=0;i<number;i++)
{
printf("Enter the number of elements - ");
scanf("%d",&count[i]);
for(j=0;i<count[i];j++)
{
printf("Enter element %d - "j);
scanf("%d",&n[i].elements[j]);
}
}
for(i=0;i<number;i++)
temp[i]=0;
for(i=0;i<number;i++)
mult*=count[i];
printf("%d\n",mult);
mult_count=0;
while(1)
{
print();
mult_count++;
if(mult_count==mult)
break;
i=0;
while(1)
{
temp[i]++;
if(temp[i]==count[i])
{
temp[i]=0;
i++;
}
else break;
}
}
return 0;
}
void print()
{
int i;
for(i=0;i<number;i++)
{
printf("%d\n",n[i].elements[temp[i]]);
printf("\n");
}
}
答案 4 :(得分:1)
只是为了好玩:
using CSScriptLibrary;
using System;
using System.Collections.Generic;
namespace LinqStringTest
{
public class Program
{
static void Main(string[] args)
{
var lists = new List<List<int>>() {
new List<int> { 0, 1, 2, 3 },
new List<int> { 4, 5 },
new List<int> { 6, 7 },
new List<int> { 10,11,12 },
};
var code = GetCode(lists);
AsmHelper scriptAsm = new AsmHelper(CSScript.LoadCode(code));
var result = (IEnumerable<dynamic>)scriptAsm.Invoke("Script.LinqCombine", lists);
foreach (var item in result)
{
Console.WriteLine(item);
}
Console.ReadLine();
}
private static string GetCode(List<List<int>> listsToCombine)
{
var froms = "";
var selects = "";
for (int i = 0; i < listsToCombine.Count; i++)
{
froms += string.Format("from d{0} in lists[{0}]{1}", i, Environment.NewLine);
selects += string.Format("D{0} = d{0},", i);
}
return @"using System;
using System.Linq;
using System.Collections.Generic;
public class Script
{
public static IEnumerable<dynamic> LinqCombine(List<List<int>> lists)
{
var x = " + froms + @"
select new { " + selects + @" };
return x;
}
}";
}
}
}
答案 5 :(得分:1)
public static List<List<string>> CrossProduct(List<List<string>> s)
{
if (!s.Any())
return new List<List<string>>();
var c1 = s.First();
var cRest = s.Skip(1).ToList();
var sss = from v1 in c1
from vRest in CrossProduct(cRest)
select (new[] { v1 }.Concat(vRest)).ToList();
var r = sss.ToList();
return r;
}
答案 6 :(得分:1)
Abhijeet Nagre的绝佳解决方案。如果某些系列为空或系列为空,则会有小的改进。
List<List<T>> generatedCombinations =
collectionOfSeries.Where(l => l.Any())
.Take(1)
.DefaultIfEmpty(new List<T>())
.First()
.Select(i => (new T[]{i}).ToList())
.ToList();
答案 7 :(得分:0)
从输入列表中生成所有组合
var combinations = AllCombinationsOf(A, B, C);
public static IEnumerable<List<T>> AllCombinationsOf<T>(params List<T>[] inputs)
{
var seed = Enumerable.Repeat(new List<T>(), 1);
return inputs.Aggregate(seed, CreateCombinations);
}
private static IEnumerable<List<T>> CreateCombinations<T>(IEnumerable<List<T>> oldCombinations, List<T> newValues)
=> from value in newValues
from combination in oldCombinations
select new List<T>(combination) {value};
this answer 的简化版 @Garry Shutler。
Try it online!(包含在问题示例中的测试用例)
答案 8 :(得分:0)
没有 Linq 和递归的解决方案:
private List<List<T>> GetAllCombinations<T>(List<List<T>> source)
{
List<List<T>> result = new List<List<T>>();
foreach (var value in source[0])
{
result.Add(new List<T> { value });
}
for (int i = 1; i < source.Count; i++)
{
var resultCount = result.Count;
for (int j = 1; j < source[i].Count; j++)
{
for (var k = 0; k < resultCount; k++)
{
result.Add(new List<T>(result[k]));
}
}
var t = (result.Count / source[i].Count);
for (int j = 0; j < source[i].Count; j++)
{
for (int k = 0; k < t; k++)
{
result[j * t + k].Add(source[i][j]);
}
}
}
return result;
}