计算字符串的所有可能组合,并加以扭曲

我试图允许用户在文本框中输入文本,并让程序生成所有可能的组合,除了最少3个字符,最多6个字符。我不需要像’as’这样无用的单词, ‘a’,’i’,’to’等混乱我的arrays。 我还将根据字典检查每个组合,以确保它是一个真正的单词。

我有完整的字典(精心制作, 这里是一个回复的链接 (警告:巨大的加载时间(对我而言)!)

无论如何,如果用户输入’ABCDEF’(没有特定的顺序),我怎么能生成,例如:

'ABC' 'BAC' 'CAB' ... 'ABD' 'ABE' 'ABF' 

等……无论什么顺序,每种可能的组合? 我知道这些组合有一些荒谬的组合,但它只需要计算一次,所以我不太担心。

我发现代码示例以递归方式找到固定宽度字符串(ABCDEF,ABCDFE … ACDBFE等)的组合(不是排列,我不需要那些)。 他们没有做我需要的事情,而且我对这个项目的起点也没有丝毫的线索。

这不是作业,它开始是我的个人项目,这个项目已经成长为一个简单的问题……我无法相信我无法理解这一点!

听起来像你在描述Power Set

这是我在个人图书馆里面的一个实现:

 // Helper method to count set bits in an integer public static int CountBits(int n) { int count = 0; while (n != 0) { count++; n &= (n - 1); } return count; } public static IEnumerable> PowerSet( IEnumerable src, int minSetSize = 0, int maxSetSize = int.MaxValue) { // we want fast random access to the source, so we'll // need to ToArray() it var cached = src.ToArray(); var setSize = Math.Pow(2, cached.Length); for(int i=0; i < setSize; i++) { var subSetSize = CountBits(i); if(subSetSize < minSetSize || subSetSize > maxSetSize) { continue; } T[] set = new T[subSetSize]; var temp = i; var srcIdx = 0; var dstIdx = 0; while(temp > 0) { if((temp & 0x01) == 1) { set[dstIdx++] = cached[srcIdx]; } temp >>= 1; srcIdx++; } yield return set; } yield break; } 

还有一个快速测试台:

 void Main() { var src = "ABCDEF"; var combos = PowerSet(src, 3, 6); // hairy joins for great prettiness Console.WriteLine( string.Join(" , ", combos.Select(subset => string.Concat("[", string.Join(",", subset) , "]"))) ); } 

输出:

 [A,B,C] , [A,B,D] , [A,C,D] , [B,C,D] , [A,B,C,D] , [A,B,E] , [A,C,E] , [B,C,E] , [A,B,C,E] , [A,D,E] , [B,D,E] , [A,B,D,E] , [C,D,E] , [A,C,D,E] , [B,C,D,E] , [A,B,C,D,E] , [A,B,F] , [A,C,F] , [B,C,F] , [A,B,C,F] , [A,D,F] , [B,D,F] , [A,B,D,F] , [C,D,F] , [A,C,D,F] , [B,C,D,F] , [A,B,C,D,F] , [A,E,F] , [B,E,F] , [A,B,E,F] , [C,E,F] , [A,C,E,F] , [B,C,E,F] , [A,B,C,E,F] , [D,E,F] , [A,D,E,F] , [B,D,E,F] , [A,B,D,E,F] , [C,D,E,F] , [A,C,D,E,F] , [B,C,D,E,F] , [A,B,C,D,E,F] 

执行此操作的最佳方法是使用for循环并将每个字符从int转换为char并将它们连接在一起。

例如:

 for(int i = 0; i < 26; i++) { Console.WriteLine((char)i + 'A'); } 

假设,你也想要像“AAB”这样的东西,你的字母组的“交叉产品”应该是它。

生成可以像LINQ一样简单:

  string myset = "ABCDE"; var All = (from char l1 in myset from char l2 in myset from char l3 in myset select new string(new char[] { l1, l2, l3})).ToList(); 

注意:构造很多字符串和char数组并不快 。 您可能希望用自定义类替换新字符串和新char [],如下所示:

 select new MyCustomClass(l1, l2, l3).ToList(); 

如果您不想要“AAB”(或“EEL”)之类的东西,那么我会将您指向维基百科以获取“组合”。

要从固定长度到“从3到6的任何长度”连接多个集合,如果限制是动态的,则使用循环。

从此链接 (在麻省理工学院许可下)

 using System; using System.Collections.Generic; using System.Diagnostics; // Copyright (c) 2010 Alex Regueiro // Licensed under MIT license, available at . // Published originally at . // Version 1.0, released 22nd May 2010. public static class CombinatoricsUtilities { // Error messages private const string errorMessageValueLessThanZero = "Value must be greater than zero, if specified."; private const string errorMessagesIndicesListInvalidSize = "List of indices must have same size as list of elements."; ///  /// Gets all permutations (of a given size) of a given list, either with or without reptitions. ///  /// The type of the elements in the list. /// The list of which to get permutations. /// The action to perform on each permutation of the list. /// The number of elements in each resulting permutation; or  to get /// premutations of the same size as . ///  to get permutations with reptition of elements; ///  to get permutations without reptition of elements. ///  is . -or- ///  is . ///  is less than zero. ///  /// The algorithm performs permutations in-place.  is however not changed. ///  public static void GetPermutations(this IList list, Action> action, int? resultSize = null, bool withRepetition = false) { if (list == null) throw new ArgumentNullException("list"); if (action == null) throw new ArgumentNullException("action"); if (resultSize.HasValue && resultSize.Value <= 0) throw new ArgumentException(errorMessageValueLessThanZero, "resultSize"); var result = new T[resultSize.HasValue ? resultSize.Value : list.Count]; var indices = new int[result.Length]; for (int i = 0; i < indices.Length; i++) indices[i] = withRepetition ? -1 : i - 1; int curIndex = 0; while (curIndex != -1) { indices[curIndex]++; if (indices[curIndex] == list.Count) { indices[curIndex] = withRepetition ? -1 : curIndex - 1; curIndex--; } else { result[curIndex] = list[indices[curIndex]]; if (curIndex < indices.Length - 1) curIndex++; else action(result); } } } ///  /// Gets all combinations (of a given size) of a given list, either with or without reptitions. ///  /// The type of the elements in the list. /// The list of which to get combinations. /// The action to perform on each combination of the list. /// The number of elements in each resulting combination; or  to get /// premutations of the same size as . ///  to get combinations with reptition of elements; ///  to get combinations without reptition of elements. ///  is . -or- ///  is . ///  is less than zero. ///  /// The algorithm performs combinations in-place.  is however not changed. ///  public static void GetCombinations(this IList list, Action> action, int? resultSize = null, bool withRepetition = false) { if (list == null) throw new ArgumentNullException("list"); if (action == null) throw new ArgumentNullException("action"); if (resultSize.HasValue && resultSize.Value <= 0) throw new ArgumentException(errorMessageValueLessThanZero, "resultSize"); var result = new T[resultSize.HasValue ? resultSize.Value : list.Count]; var indices = new int[result.Length]; for (int i = 0; i < indices.Length; i++) indices[i] = withRepetition ? -1 : indices.Length - i - 2; int curIndex = 0; while (curIndex != -1) { indices[curIndex]++; if (indices[curIndex] == (curIndex == 0 ? list.Count : indices[curIndex - 1] + (withRepetition ? 1 : 0))) { indices[curIndex] = withRepetition ? -1 : indices.Length - curIndex - 2; curIndex--; } else { result[curIndex] = list[indices[curIndex]]; if (curIndex < indices.Length - 1) curIndex++; else action(result); } } } ///  /// Gets a specific permutation of a given list. ///  /// The type of the elements in the list. /// The list to permute. /// The indices of the elements in the original list at each index in the permuted list. ///  /// The specified permutation of the given list. ///  is . -or- ///  is . ///  does not have the same size as /// . public static IList Permute(this IList list, IList indices) { if (list == null) throw new ArgumentNullException("list"); if (indices == null) throw new ArgumentNullException("indices"); if (list.Count != indices.Count) throw new ArgumentException(errorMessagesIndicesListInvalidSize, "indices"); var result = new T[list.Count]; for (int i = 0; i < result.Length; i++) result[i] = list[indices[i]]; return result; } }