在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
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 + s2
或s2 + s1
。
最简单的方法是做一个嵌套的for循环,并尝试每个组合并测试它的长度是否为6。比如:
For <each string> AS a
For <every string> AS b
If (a+b).length = 6 then
// we have a match!
我把它留给你翻译成实际的代码
您已经知道如何连接两个字符串。您还知道如何检查字符串的长度。
因此,从第一个列表中的项创建一个新列表,并排除长度为!= 6的项。