【问题标题】:C# How to manipulate a list to build words from different chars?C#如何操作列表以从不同的字符构建单词?
【发布时间】:2019-02-27 05:46:18
【问题描述】:

我正在编写一个程序,它接收多个字母,从中构建单词并返回可以在单词库(如英语词典)中找到的有意义的单词。

首先,我从两个 for 循环开始,它们接受一个字母并按升序添加所有其他字母:如果我给出 (A, D, B, H),输出将是:AD、ADB、ADBH、DA 、DAB、DABH 等。

var scrambledWords = new List<string>();

for (int i = 0; i < buildingMaterial.Count; i++)
{
    firstBuildUp = buildingMaterial[i];

    for (int j = 1; j < buildingMaterial.Count; j++)
    {
        if (buildingMaterial[j] == buildingMaterial[i])
            continue;

        firstBuildUp += buildingMaterial[j];
        scrambledWords.Add(firstBuildUp);
    }
}

现在我正在尝试找出获得这些字母的所有其他组合的最佳方法。

  • 是否有更多的 for 循环,但条件括号中的条件不同?
  • 是否为每个字母创建新列表并单独操作每个列表,然后将它们组合在一起?
  • 是使用 Linq 吗?

我正在尝试更多不同条件的 for 循环,但想知道这是否是实现我目标的最佳方式。

【问题讨论】:

    标签: c# list for-loop


    【解决方案1】:

    您正在寻找的是一个集合的所有可能子集,或者更好地说,一个集合的PowerSet。你可以有一个扩展方法来查找幂集:

    public static class ListExtensions
    {
        public static List<List<T>> PowerSet<T>(this List<T> set)
        {
            var n = set.Count;
    
            var powerSetCount = 1 << n;
    
            var result = new List<List<T>>();
    
            for (var setMask = 0; setMask < powerSetCount; setMask++)
            {
                var subset = new List<T>();
                for (var i = 0; i < n; i++)
                {
                    if ((setMask & (1 << i)) > 0)
                    {
                        subset.Add(set[i]);
                    }
                }
    
                result.Add(subset);
            }
    
            return result;
        }
    }
    

    然后像这样使用它

    static class Program
    {
        static void Main()
        {
            var powerSet = "abc".ToList().PowerSet();
    
            foreach (var set in powerSet)
            {
                // set will be a list of chars, which is equivalent to a string
                Console.WriteLine($"{new string(set.ToArray())}");
            }
    
            Console.ReadLine();
        }
    }
    

    输出将是:

    a
    b
    ab
    c
    ac
    bc
    abc
    

    注意空集也是PowerSet的一部分

    编辑:

    字符串扩展版本:

    public static class StringExtensions
    {
        public static List<string> PowerSet(this string str)
        {
            var n = str.Length;
    
            var powerSetCount = 1 << n;
    
            var result = new List<string>();
    
            for (var setMask = 0; setMask < powerSetCount; setMask++)
            {
                var subset = new StringBuilder();
                for (var i = 0; i < n; i++)
                {
                    if ((setMask & (1 << i)) > 0)
                    {
                        subset.Append(str[i]);
                    }
                }
    
                result.Add(subset.ToString());
            }
    
            return result;
        }
    }
    

    【讨论】:

    • 谢谢哈维尔,它看起来完全符合我的要求。我从未听说过超级套装或“左移运算符”,所以感谢您向我介绍它们。现在我将去了解更多关于它们并在我的程序中实现它
    • 必须使用List>?我在我的项目中理解和实施您的解决方案时遇到了一些麻烦。在我的项目中,我从用户那里收到一个字符串,在通过您的解决方案运行它之后,我想查看可能性列表中的项目是否与我使用的文本源匹配。
    • @MetaDude 不需要!通过稍微更改代码,您可以让它接收一个字符串,我会更新我的答案
    猜你喜欢
    • 1970-01-01
    • 2011-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-31
    • 1970-01-01
    • 1970-01-01
    • 2015-07-26
    相关资源
    最近更新 更多