有效回文OJ
Valid palindrome OJ
给定一个字符串,确定它是否是回文,只考虑字母数字字符,忽略大小写。例如"一个人,一个计划,一条运河:巴拿马"是一个回文。"赛车"不是一个回文。
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;
}
};
错误答案:输入:"!bHvX!?!!vHbX"输出:true应为:false
它怎么了?
不要使用"幻数"。考虑到除了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]);
您永远不会将最后一个字符转换为小写,因为循环条件是k<j和j是最后一个字符的索引。将循环更改为:
for (int k = 0; k <= j; ++k)
s[k] = tolower(s[k]);
此外,如果使用字符常量(如'a'
)而不是ASCII代码,则代码将更易于阅读。
您可以在两个方向上遍历字符串,直到指针相遇。它将是这样的:
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
。
使用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
}
};
相关文章:
- C++:正在检查LinkedList中的回文-递归方法-错误
- Usaco第1.6节主要回文
- 最大的回文产品 - 程序未运行,编写解决方案但无法理解问题
- 将 S1 转换为回文,并将 S2 作为其子字符串
- 数回文词
- 最长的回文子串(C++帮助)
- 有人可以详细解释这个回文代码是如何工作的吗?
- 回文递归版本
- 如何检查C ++ STL列表是否为回文?
- 回文数在 1 到 10000 之间
- C++ - 检查结构数据类型中的单词是否为回文
- 是回文作业练习
- 回文递归不停止
- 整数数组中最长的回文
- 回文测试
- 最大的回文产品(Project Euler)——C++
- C++ 回文程序总是给出 0(假)作为输出问题;我的代码哪里有问题?
- 递归回文问题的时间复杂度,C++
- 程序以查找给定字符串中回文的子字符串的数量
- 有效回文OJ