如何获得arraylist的所有组合?
我有一个字符串“abcde”的arraylist我想要一个方法来返回另一个arraylist与C#中的给定arraylist(例如:ab,ac,ad …)的所有可能组合
谁知道一个简单的方法?
注意:长度为2的所有可能组合,如果长度可变(可以更改)会更好
与您的评论有关,要求组合长度为2:
string s = "abcde"; var combinations = from c in s from d in s.Remove(s.IndexOf(c), 1) select new string(new[] { c, d }); foreach (var combination in combinations) { Console.WriteLine(combination); }
响应任何长度的编辑:
static IEnumerable GetCombinations(string s, int length) { Guard.Against(s == null); if (length > s.Length || length == 0) { return new[] { String.Empty }; if (length == 1) { return s.Select(c => new string(new[] { c })); } return from c in s from combination in GetCombinations( s.Remove(s.IndexOf(c), 1), length - 1 ) select c + combination; }
用法:
string s = "abcde"; var combinations = GetCombinations(s, 3); Console.WriteLine(String.Join(", ", combinations));
输出:
abc, abd, abe, acb, acd, ace, adb, adc, ade, aeb, aec, aed, bac, bad, bae, bca, bcd, bce, bda, bdc, bde, bea, bec, bed, cab, cad, cae, cba, cbd, cbe, cda, cdb, cde, cea, ceb, ced, dab, dac, dae, dba, dbc, dbe, dca, dcb, dce, dea, deb, dec, eab, eac, ead, eba, ebc, ebd, eca, ecb, ecd, eda, edb, edc
这是我的generics函数,它可以返回T类型的所有组合:
static IEnumerable> GetCombinations(IEnumerable list, int length) { if (length == 1) return list.Select(t => new T[] { t }); return GetCombinations(list, length - 1) .SelectMany(t => list, (t1, t2) => t1.Concat(new T[] { t2 })); }
用法:
Console.WriteLine( string.Join(", ", GetCombinations("abcde".ToCharArray(), 2).Select(list => string.Join("", list)) ) );
输出:
aa, ab, ac, ad, ae, ba, bb, bc, bd, be, ca, cb, cc, cd, ce, da, db, dc, dd, de, ea, eb, ec, ed, ee
更新请在此处查看我的答案,了解其他情况,例如排列和k组合等。
通过仅使用数组和递归来组合数组中的数字:
static int n = 4; int[] baseArr = { 1, 2, 3, 4 }; int[] LockNums; static void Main(string[] args) { int len = baseArr.Length; LockNums = new int[n]; for (int i = 0; i < n; i++) { int num = baseArr[i]; DoCombinations(num, baseArr, len); //for more than 4 numbers the print screen is too long if we need to check the result next line will help //Console.ReadLine(); } } private void DoCombinations(int lockNum, int[] arr, int arrLen ) { int n1 = arr.Length; // next line shows the difference in length between the previous and its previous array int point = arrLen - n1; LockNums[n - arr.Length] = lockNum; int[] tempArr = new int[arr.Length - 1]; FillTempArr(lockNum, arr, tempArr); //next condition will print the last number from the current combination if (arr.Length == 1) { Console.Write(" {0}", lockNum); Console.WriteLine(); } for (int i = 0; i < tempArr.Length; i++) { if ((point == 1) && (i != 0)) { //without this code the program will fail to print the leading number of the next combination //and 'point' is the exact moment when this code has to be executed PrintFirstNums(baseArr.Length - n1); } Console.Write(" {0}", lockNum); int num1 = tempArr[i]; DoCombinations(num1, tempArr, n1); } } private void PrintFirstNums(int missNums) { for (int i = 0; i < missNums; i++) { Console.Write(" {0}", LockNums[i]); } } private void FillTempArr(int lockN, int[] arr, int[] tempArr) { int idx = 0; foreach (int number in arr) { if (number != lockN) { tempArr[idx++] = number; } } } private void PrintResult(int[] arr) { foreach (int num in arr) { Console.Write(" {0}", num); } }