日期:2014-05-18 浏览次数:21084 次
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { string s = "ABCD"; List<string> list = new List<string>(); foreach (var i in Combo(s, 4)) { list = list.Union(Arrange(i)).ToList(); } list.ForEach(x => Console.WriteLine(x)); } static IEnumerable<string> Arrange(string source) { for (int i = 0; i < source.Length; i++) { if (source.Length == 1) { yield return source; } else { foreach (var x in Arrange(source.Substring(0, i) + source.Substring(i + 1))) { yield return source[i] + x; } } } } static IEnumerable<string> Combo(string source, int len) { int[] pos = new int[len]; for (int i = 0; i < len; i++) pos[i] = i; while (pos[0] < source.Length - len) { string str = ""; for (int i = 0; i < len; i++) str += source[pos[i]]; for (int i = len - 1; i >= 0; i--) { if (pos[i] < source.Length - len + i) { pos[i]++; for (int j = i + 1; j <= len - 1; j++) { pos[j] = pos[i] + j - i; } break; } else { continue; } } yield return str; } yield return source.Substring(source.Length - len); } } }
------解决方案--------------------
另外,写为Linq查询表达式也是一样的。因为Linq也会使用yield迭代器来延迟计算,所以不用担心Linq的效率问题。使用Linq看起来逻辑上更优雅:
using System; using System.Collections.Generic; using System.Linq; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { 排列组合("ABC", 0, 3).ToList().ForEach(x => { Console.WriteLine(x); }); Console.ReadKey(); } private static IEnumerable<string> 排列组合(string source, int fr, int len) { if (len == 1) return new List<string> { source.Substring(fr, 1) }; else return from sub in 排列组合(source, fr + 1, len - 1) from i in Enumerable.Range(0, sub.Length + 1) let first = source.Substring(fr, 1) select sub.Insert(i, first); } } }