复杂的回文单词



我有一个方法,可以检查它是否是回文

public bool IsPalindrome(PalindromeModel model)
{
// First, check whether input string is null or whitespace.
// If yes, then return false.
if (string.IsNullOrWhiteSpace(model.Value))
return false;
var inputDict = new Dictionary<char, int>();
// Big/small letter is not important
var lowerInputStr = model.Value.ToLower();
// Fill input dictionary
// If hit a space, then skip it
for (var i = 0; i < lowerInputStr.Length; i++)
{
if (lowerInputStr[i] != ' ')
{
if (inputDict.ContainsKey(lowerInputStr[i]))
inputDict[lowerInputStr[i]] += 1;
else
inputDict.Add(lowerInputStr[i], 1);
}
}
var countOdds = 0;
foreach (var elem in inputDict)
{
if (elem.Value % 2 != 0)
countOdds++;
}
return countOdds <= 1;
}

因此,它与以下单词一起工作:doodA Santa Lived As a Devil At NASA

但对于像Mr. Owl Ate My Metal Worm这样更复杂的回文,它返回false,但它应该是true,我如何实现这一点?

删除第一个循环之前的空格和标点符号

var lowerInputStr = new string(model.Value
.ToCharArray()
.Where(c => !char.IsPunctuation(c)).ToArray())
.ToLower()
.Replace(" ", "");

该解决方案看起来过于复杂。我只是从两边走进去,跳过任何你没有定义为在比较范围内的字符。在这个实现中,我只考虑字母而忽略大小写。注意,该解决方案不分配任何额外的内存(例如string.Replace()string.ToLower()在内部所做的(,并在O(N(中运行最坏情况下的输入(它是一个palendrome(。

bool IsPalendrome(string input)
{
var left = 0;
var right = input.Length - 1;
while (left < right)
{
left = SkipNonLetters(input, left, 1);
right = SkipNonLetters(input, right, -1);

if (char.ToUpperInvariant(input[left]) != char.ToUpperInvariant(input[right]))
return false;

left++;
right--;
}

return true;
}
int SkipNonLetters(string input, int startAt, int direction)
{
while (startAt >= 0 && startAt < input.Length && !char.IsLetter(input[startAt]))
startAt += direction;

return startAt;
}

示例:

Console.WriteLine(IsPalendrome("dood"));
Console.WriteLine(IsPalendrome("A Santa Lived As a Devil At NASA"));
Console.WriteLine(IsPalendrome("Mr. Owl Ate My Metal Worm"));

输出:

True
True
True

要扩展Muhammad Sulaiman所说的内容,在清理完字符串后,该方法的其余部分可以简单得多

var lowerInputStr = new string(input.ToCharArray()
.Where(c => !char.IsPunctuation(c))
.ToArray())
.ToLower()
.Replace(" ", ""); 

return lowerInputStr.Substring(lowerInputStr.Length / 2) == (new String(lowerInputStr.Reverse().ToArray()))
.Substring(lowerInputStr.Length / 2);

最新更新