7

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

Floern
  • 33,559
  • 24
  • 104
  • 119
manu
  • 1,807
  • 4
  • 25
  • 32
  • This sounds a lot like a homework question. Could you update your posting with the code you've tried so far, and tell us where you're getting stuck? – Richard Ev Dec 10 '10 at 15:01
  • 2
    So I take it you aren't checking to see if it's an actual word, just generating every possible coimbination of letters? – Neil N Dec 10 '10 at 15:02
  • The answer to this will be almost the same as the answers here: https://stackoverflow.com/questions/3763011/c-algorithm-that-re-arranges-chars-in-a-string – Tim Robinson Dec 10 '10 at 14:32

3 Answers3

4

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
Grozz
  • 8,317
  • 4
  • 38
  • 53
0

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.

Mitch Schwartz
  • 1,503
  • 9
  • 9
0

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();
Dean Chalk
  • 20,076
  • 6
  • 59
  • 90
  • Dear Dean, many thanks for the response but it will provide CAT CTA ACT ATC TAC TCA It will not provide CA, CT and so on. Any idea on this please... – manu Dec 10 '10 at 17:02