在c#中过滤字符串列表

本文关键字:字符串 列表 过滤 | 更新日期: 2023-09-27 18:10:34

我通过阅读一本书和其他在线教程(homeandlearn.co.uk)来学习c#

我已经成功地做了FizzBuzz练习,但在下面的练习中挣扎。如有任何帮助,我将不胜感激。

请详细解释一下,以便我也能学习。

运动

过滤一个字符串列表,该列表应该只传递六个字母的字符串,这些字符串由列表中两个连接的较小字符串组成。

例如,给定列表

acks, top, cat, gr, by, bar,lap, st, ely, ades

列表应该返回

堆栈,笔记本电脑,成绩,几乎

因为它们是另外两个字符串的连接:

st + acks = stacks

lap + top = laptop

gr + ades = grades

bar + Ely = barely

在c#中过滤字符串列表

In LINQ:

// The strings (it's equivalent to new string[])
var strs = new[] { "acks", "top", "cat", "gr", "by", "bar", "lap", "st", "ely", "ades" };
// We group the strings by length.
var strsByLength = strs.ToLookup(p => p.Length);
// For each string we match the string with all the strings with the "right" length (6 - current string length) and we sum them (p, q) => p + q.
var result = strs.SelectMany(p => strsByLength[6 - p.Length], (p, q) => p + q);

我使用ToLookup使这个问题的"中等"复杂性略小于O(n^2)。显然,如果所有字符串都是长3,问题仍然是O(n^2)。

我使用的SelectMany,单独来说,是有点高级的LINQ。

我补充一下,如果你有一本"好"词的字典,一个解决方案可能是这样的。它使用字典作为一个黑盒:你可以检查一个单词是否在字典中(技术上是HashSet),但你不能直接使用字典来帮助你找到单词。

// The list of good words
var words = new[] { "stacks", "laptop", "grades", "barely" };
// Made in an `HashSet` to make it O(1) to check for them.
var wordsSet = new HashSet<string>(words);
// Here we create a temporary object (p, q) => new { p, q, sum = p + q } containing the two "parts" of the word and the complete word and then we filter the result for only the words contained in the wordsSet.
var result2 = strs.SelectMany(p => strsByLength[6 - p.Length], (p, q) => new { p, q, sum = p + q }).Where(p => wordsSet.Contains(p.sum));

确实有很多方法可以做到这一点。下面是一个使用配对的例子:

        //grab all possible pairings in one data structure
        List<KeyValuePair<string, string>> pairs = new List<KeyValuePair<string, string>>();
        string[] list = { "acks", "top", "cat", "gr", "by", "bar", "lap", "st", "ely", "ades" };
        foreach (string first in list)
        {
            foreach (string second in list)
            {
                pairs.Add(new KeyValuePair<string, string>(first, second));
            }
        }
        //test each pairing for length and whatever else you want really
        List<string> sixLetterWords = new List<string>();
        foreach (KeyValuePair<string, string> pair in pairs)
        {
            string testWord = pair.Key + pair.Value;
            if (testWord.Length == 6)
            {
                sixLetterWords.Add(testWord);
            }
        }

分而治之。首先,你需要找到一种方法来获得所有可能的字符串对(比如First和second, First和third,…)第二、第三等)。接下来,对于每一对,检查所讨论的列表是否包含s1 + s2s2 + s1

最简单的方法是做一个嵌套的for循环,并尝试每个组合并测试它的长度是否为6。比如:

For <each string> AS a
    For <every string> AS b
        If (a+b).length = 6 then
            // we have a match!

我把它留给你翻译成实际的代码

您已经知道如何连接两个字符串。您还知道如何检查字符串的长度。

因此,从第一个列表中的项创建一个新列表,并排除长度为!= 6的项。