7
votes

Comment écrire un générateur anagramme en pure C # et .NET Framework

Je voudrais générer une sortie anagramme d'une chaîne donnée sans l'aide de bibliothèques externes telles que Google Anagram Algorithms Helper.

Exemple:

chaîne d'entrée = "dieu"

La liste de sortie doit ressembler à celle suivante:

g o d aller gd od og dg dg do dieu gdo odg Dog DGO OGD


3 commentaires

La réponse à cela sera presque la même que les réponses ici: Stackoverflow.com/Questtions/3763011/...


Cela semble beaucoup comme une question de devoirs. Pourriez-vous mettre à jour votre publication avec le code que vous avez essayé jusqu'à présent et dites-nous où vous êtes coincé?


Donc, je suppose que vous ne vérifiez pas si c'est un mot réel, il suffit de générer toutes les cumabres possibles des lettres?


3 Réponses :


0
votes

Pour ce que ça vaut, j'ai écrit des méthodes en Java qui feront ce que vous voulez, et je comprends que c # est suffisamment similaire que vous pourrez probablement lire le code sans trop de problèmes. (La syntaxe, c'est-à-dire. Si vous n'êtes pas à l'aise avec des fonctions récursives, cela pourrait vous donner des problèmes.) Mon nom d'utilisateur est @undefined sur cette Fil du forum . Pour utiliser le code, vous pouvez boucler des valeurs K de 1 à la longueur de votre chaîne inclusive. Alternativement, vous pouvez générer tous les sous-ensembles (jeter le jeu vide) comme décrit dans ce fil puis obtenir les permutations de là. Une autre manière consiste à écrire une fonction KTH-permutation et à utiliser cela. Je n'ai pas d'affichage en ligne; celui que j'utilise est un peu désordonné et je devrais le réécrire de temps en temps.

Modifier: mérite d'être mentionné que j'ai écrit les méthodes d'une manière qui semblait facile, mais plus efficace serait d'utiliser une pile, de cette façon de ne pas avoir à créer des tonnes de nouveaux objets.


0 commentaires

0
votes

Essayez ceci xxx

utilisez simplement cette méthode d'extension de cette manière xxx


1 commentaires

Cher Dean, merci beaucoup pour la réponse, mais il fournira une loi sur la CTA ATC TAC TCA qu'il ne fournira pas de CA, CT et ainsi de suite. Toute idée sur cela s'il vous plaît ...



4
votes

Ce TAKS s'est tourné pour être génial sur tant de niveaux. Je vous présente une solution pure linq (mais pas très efficace).

    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


0 commentaires