How to write an anagram generator in pure C# and .Net framework [closed]

旧街凉风 提交于 2019-12-01 17:29:13

问题


I would like to generate anagram output of a given string without the help of any external libraries such as Google anagram algorithms helper.

Example:

Input string = "GOD"

Output list should look like the following one:

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


回答1:


That taks turned to be awesome on so many levels. I present you a pure LINQ (but not very efficient) solution.

    static class Program
    {
        static void Main(string[] args)
        {
            var res = "cat".Anagrams();

            foreach (var anagram in res)
                Console.WriteLine(anagram.MergeToStr());
        }

        static IEnumerable<IEnumerable<T>> Anagrams<T>(this IEnumerable<T> collection) where T: IComparable<T>
        {
            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<T>());

            return subsets;
        }

        public static IEnumerable<IEnumerable<T>> Permutations<T>(this IEnumerable<T> 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<char> chars)
        {
            return new string(chars.ToArray());
        }

    }// class

    // cause Distinct implementation is shit
    public class CollectionComparer<T> : IEqualityComparer<IEnumerable<T>> where T: IComparable<T>
    {
        Dictionary<IEnumerable<T>, int> dict = new Dictionary<IEnumerable<T>, int>();

        public bool Equals(IEnumerable<T> x, IEnumerable<T> y)
        {
            if (x.Count() != y.Count())
                return false;
            return x.Zip(y, (xi, yi) => xi.Equals(yi)).All(compareResult => compareResult);
        }

        public int GetHashCode(IEnumerable<T> 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



回答2:


For what it's worth, I wrote methods in Java that will do what you want, and I understand C# is similar enough you will probably be able to read the code without much trouble. (The syntax, that is. If you are not comfortable with recursive functions then that could give you trouble.) My user name is @undefined over on this forum thread. To use the code, you could loop through k-values from 1 to the length of your string inclusive. Alternatively, you could generate all subsets (discarding the empty set) as described in this thread and then get the permutations from there. Another way is to write a kth-permutation function and use that. I don't have one posted online; the one I use is a bit messy and I should rewrite it sometime.

Edit: Worth mentioning that I wrote the methods in a way that seemed easy, but more efficient would be to use a stack, that way you don't have to create tons of new objects.




回答3:


try this

public static IEnumerable<string> Permutations(this string text)
{
    return PermutationsImpl(string.Empty, text);
}

private static IEnumerable<string> 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;
        }
    }
}

then simply use this extension method this way

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


来源:https://stackoverflow.com/questions/4409773/how-to-write-an-anagram-generator-in-pure-c-sharp-and-net-framework

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!