这就是问题:
"编写一个程序,从文本中提取所有单词的文字,例如ABBA"," lamal"," exe"。 "
这是我的代码:
public static List<string> FindPalindromes()
{
string text = String.Empty;
Console.Write("Enter the text:\n\t");
text = Console.ReadLine();
List<string> answer = new List<string>();
string[] words = text.Split('.', ',', ' ', ':', '/', '\\', '"', ';');
foreach(string word in words.Where(
(string x) =>
{
if(String.Equals(x, x.Reverse()))
return true;
else
return false;
}
))
answer.Add(word);
return answer;
}
现在我认为如果我将where方法中的逻辑分离为一个返回布尔值并检查单个单词是否为回文的单独方法,它会更加整洁。但我想尝试使用lambda。
无论如何,这段代码不会返回任何内容。我怀疑问题出在if条件中。
答案 0 :(得分:6)
x.Reverse()
正在调用Enumerable.Reverse()
,它会返回IEnumerable<char>
- 而不是字符串。这就是Equals
永远不会返回true
的原因。这是另一种选择:
char[] chars = x.ToCharArray();
Array.Reverse(chars);
return x == new string(chars);
或者你可以在相反的字符序列上调用string.Join
或string.Concat
- 非常低效,但它会在单个表达式中完成工作,允许您替换{的所有内容{1}}以后:
foreach
更清洁:)每当您发现自己反复添加到列表时,请考虑使用查询和return words.Where(x => x == string.Concat(x.Reverse())
.ToList();
。你已经有了过滤部分,你只需要使用ToList()
来摆脱ToList()
循环。
同样,只要你发现自己:
foreach
... 强烈考虑重构为:
if (condition)
return true;
else
return false;
答案 1 :(得分:3)
是的,问题出在您的String.Equals
电话中。 x.Reverse
会返回IEnumerable<char>
,它永远不会等同于您的字符串。尝试:
if(String.Equals(x, new string(x.Reverse().ToArray()))
答案 2 :(得分:2)
您的代码可以更改为:
answer = words.Where(x => String.Join("", x.Reverse()) == x).ToList();
答案 3 :(得分:1)
x.Reverse
不是字符串,而是IEnumerable<char>
。您需要将该字符序列转换回字符串,以将其与另一个字符串进行比较。那个,或者使用比较工具来比较两个序列而不是两个字符串,因为你没有字符串:
return words.Where(word => word.SequenceEqual(word.Reverse()))
.ToList();
答案 4 :(得分:1)
我会像这样重写它:
public static List<string> FindPalindromes() {
Console.Write("Enter the text:\n\t");
string text = Console.ReadLine();
string[] words = text.Split('.', ',', ' ', ':', '/', '\\', '"', ';');
return words.Where(word => word.Reverse().SequenceEqual(word)).ToList();
}
这会有很多变化。
List
来存储结果。这对于linq来说是不必要的。if
语句。这是不必要的,因为它的唯一目的是返回true或false,这是if
条件中已有的值。.SequenceEqual
正确比较两个序列中的字符。