另一个排列词难题......与Linq?

时间:2010-12-17 15:34:33

标签: linq permutation combinations

我已经看过许多获得给定字母集的所有排列的例子。递归似乎可以很好地得到一组字母的所有可能组合(尽管如果其中两个字母是相同的,它似乎没有考虑到。)

我想弄清楚的是,您是否可以使用linq(或不使用)来获得所有可能的字母组合,最多可达3个字母组合。

例如,给出字母:P I G G Y. 我想要一系列这些字母的所有可能的组合,以便我可以查看单词列表(拼字游戏?)并最终得到一个列表,列出你可以使用这些字母创建的所有可能的单词(从3个字母到总数,在此案例5个字母)。

4 个答案:

答案 0 :(得分:9)

答案 1 :(得分:1)

这种方法似乎有效。它使用Linq和程序代码。

IEnumerable<string> GetWords(string letters, int minLength, int maxLength)
{
    if (maxLength > letters.Length)
        maxLength = letters.Length;

    // Associate an id with each letter to handle duplicate letters
    var uniqueLetters = letters.Select((c, i) => new { Letter = c, Index = i });

    // Init with 1 zero-length word
    var words = new [] { uniqueLetters.Take(0) };

    for (int i = 1; i <= maxLength; i++)
    {
        // Append one unused letter to each "word" already generated
        words = (from w in words
                 from lt in uniqueLetters
                 where !w.Contains(lt)
                 select w.Concat(new[] { lt })).ToArray();

        if (i >= minLength)
        {
            foreach (var word in words)
            {
                // Rebuild the actual string from the sequence of unique letters
                yield return String.Join(
                    string.Empty,
                    word.Select(lt => lt.Letter));
            }
        }
    }
}

答案 2 :(得分:1)

搜索单词的所有排列的问题是计算绝对乱码所花费的工作量。生成所有排列是O(n!)并且sooo大部分都将被绝对浪费。这就是为什么我建议给予回答

这是一个返回所有排列的递归linq函数:

    public static IEnumerable<string> AllPermutations(this IEnumerable<char> s) {
        return s.SelectMany(x => {
            var index = Array.IndexOf(s.ToArray(),x);
            return s.Where((y,i) => i != index).AllPermutations()
                    .Select(y => new string(new [] {x}.Concat(y).ToArray()))
                    .Union(new [] {new string(new [] {x})});
        }).Distinct();
    }

你可以找到你想要的单词:

"piggy".AllPermutations().Where(x => x.Length > 2)

然而:

警告:喜欢非常效率低下的答案

现在linq对我来说最大的好处就是它的可读性。尽管如此,我认为上述代码的意图并不清楚(我写了它!)。因此,linq(对我而言)的最大优势不在于上面,它不如非linq解决方案那么有效。我通常原谅linq缺乏执行效率,因为它为编码时间,可读性和易维护性增加了效率,但我只是不认为linq解决方案最适合这里...方形挂钩,圆孔排序如果你愿意的话。

此外,还有我上面提到的复杂性问题。当然它可以在.2秒内找到153个三个字母或更多的“小猪”排列,但是给它一个像'簿记员'的单词,你将等待一个坚实的 1分39秒找到所有435,574个三个字母或更多的排列。那我为什么发布这么糟糕的功能呢?为了说明必须采取正确的方法。生成所有排列并不是解决这个问题的有效方法。

答案 3 :(得分:0)