如何在纯C#和.Net框架中编写anagram生成器

我想在没有任何外部库(如Google anagram algorithm helper)的帮助下生成给定字符串的anagram输出。

例:

输入字符串=“GOD”

输出列表应如下所示:

GOD GO GD OD OG DG DO GOD GDO ODG OGD DGO DOG

在很多层面上,这一点变得非常棒。 我向您介绍一个纯LINQ(但不是非常有效)的解决方案。

static class Program { static void Main(string[] args) { var res = "cat".Anagrams(); foreach (var anagram in res) Console.WriteLine(anagram.MergeToStr()); } static IEnumerable> Anagrams(this IEnumerable collection) where T: IComparable { var total = collection.Count(); // provided str "cat" get all subsets c, a, ca, at, etc (really nonefficient) var subsets = collection.Permutations() .SelectMany(c => Enumerable.Range(1, total).Select(i => c.Take(i))) .Distinct(new CollectionComparer()); return subsets; } public static IEnumerable> Permutations(this IEnumerable collection) { return collection.Count() > 1 ? from ch in collection let set = new[] { ch } from permutation in collection.Except(set).Permutations() select set.Union(permutation) : new[] { collection }; } public static string MergeToStr(this IEnumerable chars) { return new string(chars.ToArray()); } }// class // cause Distinct implementation is shit public class CollectionComparer : IEqualityComparer> where T: IComparable { Dictionary, int> dict = new Dictionary, int>(); public bool Equals(IEnumerable x, IEnumerable y) { if (x.Count() != y.Count()) return false; return x.Zip(y, (xi, yi) => xi.Equals(yi)).All(compareResult => compareResult); } public int GetHashCode(IEnumerable obj) { var inDict = dict.Keys.FirstOrDefault(k => Equals(k, obj)); if (inDict != null) return dict[inDict]; else { int n = dict.Count; dict[obj] = n; return n; } } }// class 

为了它的价值,我用Java编写了可以做你想要的方法,而且我理解C#足够相似你可能会毫不费力地阅读代码。 (语法,即。如果你对递归函数感到不舒服,那么可能会给你带来麻烦。)我的用户名是@undefined over此论坛post 。 要使用代码,您可以将k值从1循环到包含字符串的长度。 或者,您可以生成所有子集(丢弃空集), 如此线程中所述 ,然后从那里获取排列。 另一种方法是编写第k个置换函数并使用它。 我没有网上发布的; 我使用的那个有点乱,我应该在某个时候重写它。

编辑:值得一提的是,我以一种看似简单的方式编写方法,但更高效的是使用堆栈,这样就不必创建大量的新对象。

试试这个

 public static IEnumerable Permutations(this string text) { return PermutationsImpl(string.Empty, text); } private static IEnumerable PermutationsImpl(string start, string text) { if (text.Length <= 1) yield return start + text; else { for (int i = 0; i < text.Length; i++) { text = text[i] + text.Substring(0, i) + text.Substring(i + 1); foreach (var s in PermutationsImpl(start + text[0], text.Substring(1))) yield return s; } } } 

然后只需使用这种扩展方法

 string text = "CAT"; List perms = text.Permutations().ToList();