我正在通过阅读书籍和其他在线教程(homeandlearn.co.uk)学习C#
我设法做了FizzBuzz练习,但是在下面的练习中挣扎。任何帮助将非常感激。
请详细解释,以便我可以学习。
过滤一个字符串列表,这些字符串只能传递六个字母字符串,这些字符串由列表中的两个连接的较小字符串组成。
例如,给定列表
acks,top,cat,gr,by,bar,lap,st,ely,ades
列表应该返回
堆栈,笔记本电脑,成绩,勉强
因为这些是两个其他字符串的串联:
st + acks = stacks
lap + top = laptop
gr + ades =成绩
bar + ely =勉强
答案 0 :(得分:1)
在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));
答案 1 :(得分:0)
分而治之。首先,你需要找到一种方法来获得所有可能的字符串对(例如第一和第二,第一和第三,......,第二和第三等)。接下来,对于每对,您检查相关列表是否包含s1 + s2
或s2 + s1
。
答案 2 :(得分:0)
最简单的方法是做一个嵌套的for循环,并尝试每个组合并测试它是否长度为6。类似的东西:
For <each string> AS a
For <every string> AS b
If (a+b).length = 6 then
// we have a match!
我会留给您将其翻译成实际代码
答案 3 :(得分:0)
您已经知道如何连接两个字符串。您还知道如何检查字符串的长度。
因此,从第一个列表中的项目创建一个新列表,并排除长度为!= 6的项目。
答案 4 :(得分:0)
有很多方法可以做到这一点。这是一个使用配对的方法:
//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);
}
}