如何用一个来解这个
本文关键字:何用一 | 更新日期: 2023-09-27 18:12:36
这就是问题所在:
"编写程序,从文本中提取所有回文词,如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方法中的逻辑分离到一个单独的方法中,该方法返回一个布尔值并检查单个单词是否为回文,则会更整洁。但我想试试用。
无论如何,这段代码没有返回任何东西。我怀疑问题在if条件
x.Reverse()
正在调用Enumerable.Reverse()
,它将返回一个IEnumerable<char>
- 而不是字符串。这就是为什么Equals
永远不会返回true
。这是另一个选项:
char[] chars = x.ToCharArray();
Array.Reverse(chars);
return x == new string(chars);
或者您可以在反向的字符序列上调用string.Join
或string.Concat
-效率非常低,但它将在单个表达式中完成工作,允许您替换foreach
之后的所有内容:
return words.Where(x => x == string.Concat(x.Reverse())
.ToList();
干净多了:)任何时候你发现自己在重复添加一个列表,考虑使用查询和ToList()
。您已经得到了过滤部分,您只需要使用ToList()
来摆脱foreach
循环。
同样的,任何时候你发现自己有:
if (condition)
return true;
else
return false;
…强考虑重构为:
return condition;
是的,问题是在你的String.Equals
呼叫。x.Reverse
返回一个IEnumerable<char>
,它永远不会等于你的字符串。试一试:
if(String.Equals(x, new string(x.Reverse().ToArray()))
您的代码可以更改为:
answer = words.Where(x => String.Join("", x.Reverse()) == x).ToList();
x.Reverse
不是字符串,它是IEnumerable<char>
。您需要将该字符序列转换回字符串,以便与另一个字符串进行比较。或者使用比较工具来比较两个序列而不是两个字符串,因为您没有字符串:
return words.Where(word => word.SequenceEqual(word.Reverse()))
.ToList();
我会这样重写:
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
正确比较两个序列中的字符。