给定一个字符串,确定它是否是回文,只考虑字母数字字符并忽略大小写。 例如, "一个男人,一个计划,一个运河:巴拿马"是一个回文。 "赛车"不是回文。
class Solution {
public:
bool isPalindrome(string s) {
if (!s.length()) return true;
int i = 0, j = s.length() - 1;
for (int k = 0; k < j; ++k)
s[k] = tolower(s[k]);
while (i < j) {
if ((s[i] < 48)||(s[i] > 57 && s[i] < 97)||(s[i] > 122))
++i;
else if ((s[j] < 48)||(s[j] > 57 && s[j] < 97)||(s[j] > 122))
--j;
else if (s[i++] != s[j--]) return false;
}
return true;
}
};
Wrong answer: Input: "!bHvX!?!!vHbX" Output: true Expected: false
它有什么问题?
答案 0 :(得分:1)
不要使用“魔术数字”。考虑到除了ASCII之外还有EBCDIIC编码方案。
我会按照以下方式编写函数
#include <iostream>
#include <iomanip>
#include <string>
#include <cctype>
bool IsPalindrome( const std::string &s )
{
std::string::size_type i = 0, j = s.length();
do
{
while ( i != j && !std::isalnum( s[i] ) ) ++i;
while ( j != i && !std::isalnum( s[--j] ) );
} while ( i != j && std::toupper( s[i] ) == std::toupper( s[j] ) && ++i );
// Unit test:)
// std::cout << "i = " << i << ", j = " << j << std::endl;
return ( i == j );
}
int main()
{
std::string s( "A man, a plan, a canal: Panama" );
std::cout << '\"' << s << "\" is palindrome: "
<< std::boolalpha << IsPalindrome( s ) << std::endl;
s = "race a car";
std::cout << '\"' << s << "\" is palindrome: "
<< std::boolalpha << IsPalindrome( s ) << std::endl;
s = "!bHvX!?!!vHbX";
std::cout << '\"' << s << "\" is palindrome: "
<< std::boolalpha << IsPalindrome( s ) << std::endl;
return 0;
}
输出
"A man, a plan, a canal: Panama" is palindrome: true
"race a car" is palindrome: false
"!bHvX!?!!vHbX" is palindrome: false
您可以将该功能作为您班级的操作员功能。例如
struct Solution
{
bool operator ()( const std::string & ) const;
};
或者
struct IsPalindrome
{
bool operator ()( const std::string & ) const;
};
这是一个示范程序
#include <iostream>
#include <iomanip>
#include <string>
#include <cctype>
#include <vector>
#include <algorithm>
struct IsPalindrome
{
bool operator ()( const std::string &s ) const
{
std::string::size_type i = 0, j = s.length();
do
{
while ( i != j && !std::isalnum( s[i] ) ) ++i;
while ( j != i && !std::isalnum( s[--j] ) );
} while ( i != j && std::toupper( s[i] ) == std::toupper( s[j] ) && ++i );
// unit test.:)
// std::cout << "i = " << i << ", j = " << j << std::endl;
return ( i == j );
}
};
int main()
{
std::vector<std::string> v =
{
"!bHvX!?!!vHbX",
"A man, a plan, a canal: Panama",
"race a car"
};
auto it = std::find_if( v.begin(), v.end(), IsPalindrome() );
if ( it != v.end() )
{
std::cout << '\"' << *it << "\" is palindrome" << std::endl;
}
return 0;
}
输出
"A man, a plan, a canal: Panama" is palindrome
至于你的代码,那么即使在函数的第一个语句中也存在一个错误。您忘记了以下循环中字符串的最后一个字符
int i = 0, j = s.length() - 1;
for (int k = 0; k < j; ++k)
s[k] = tolower(s[k]);
答案 1 :(得分:0)
您永远不会将最后一个字符转换为小写字母,因为循环条件是k < j和j是最后一个字符的索引。将循环更改为:
for (int k = 0; k <= j; ++k)
s[k] = tolower(s[k]);
此外,如果使用'a'
等字符常量而不是ASCII代码,代码将更容易阅读。
答案 2 :(得分:0)
您可以在两个方向上遍历字符串,直到指针相遇。它将是这样的:
bool isPalindrome(std::string const& s) {
int len = s.length();
int i = 0;
int j = len - 1;
while (true) {
// Skip garbage characters.
while (i < len && !isalpha(s[i])) ++i;
while (j >= 0 && !isalpha(s[j])) --j;
if (i < j && tolower(s[i]) == tolower(s[j]))
continue;
if (i >= j)
return true;
return false;
}
请注意,len
是已签名的变量,尽管s.length()
为size_t
。
答案 3 :(得分:0)
使用 JavaScript
var isPalindrome = function (s) {
let originalStringWithoutSplChr = s.replace(/[^a-zA-Z0-9]/g, "").toLowerCase()
let newString = originalStringWithoutSplChr.split("").reverse().join("")
if (newString === originalStringWithoutSplChr) {
return true
}
else {
return false
}
};