static void Main(string[] args) { int[] a = new int[] { 1, 2, 3, 4, 5, 6, 7, 8 ,9,10,11,12}; int m = 0; // 待取出组合的个数 Combination c = new Combination(); List<int[]> list = c.combination(a, m); c.print(list); Console.WriteLine("一共" + list.Count + "组!"); }
public List<int[]> combination(int[] a, int m) { Combination c = new Combination(); List<int[]> list = new List<int[]>(); int n = a.Length; if (m == 0) { list.Add(new int[] { }); return list; } else if (m == n) { int[] temp = new int[a.Length]; a.CopyTo(temp, 0); list.Add(a); return list; } bool end = false; // 是否是最后一种组合的标记 // 生成辅助数组。首先初始化,将数组前n个元素置1,表示第一个组合为前n个数。 int[] tempNum = new int[n]; for (int i = 0; i < n; i++) { if (i < m) { tempNum[i] = 1; } else { tempNum[i] = 0; } } printVir(tempNum);// 打印首个辅助数组 list.Add(c.createResult(a, tempNum, m));// 打印第一种默认组合 int k = 0;//标记位 while (!end) { bool findFirst = false; bool swap = false; // 然后从左到右扫描数组元素值的"10"组合,找到第一个"10"组合后将其变为"01" for (int i = 0; i < n; i++) { int l = 0; if (!findFirst && tempNum[i] == 1) { k = i; findFirst = true; } if (tempNum[i] == 1 && tempNum[i + 1] == 0) { tempNum[i] = 0; tempNum[i + 1] = 1; swap = true; for (l = 0; l < i - k; l++) { // 同时将其左边的所有"1"全部移动到数组的最左端。 tempNum[l] = tempNum[k + l]; } for (l = i - k; l < i; l++) { tempNum[l] = 0; } if (k == i && i + 1 == n - m) {//假如第一个"1"刚刚移动到第n-m+1个位置,则终止整个寻找 end = true; } } if (swap) { break; } } printVir(tempNum);// 打印辅助数组 list.Add(c.createResult(a, tempNum, m));// 添加下一种默认组合 } return list; }