问题来源:Kattis 的反回文
该问题需要确定给定的文本行是否包含回文(两个或多个字符的子串,向前和向后读相同,忽略空格、标点符号和大小写)。如果存在回文,则输出应为“Palindrome”;否则,输出应该是“Anti-palindrome”。非字母字符必须被忽略,并且大小写差异被视为相同。输入内容至少包含 1 个字母字符,长度最多为 80 个字符。
这个
bool
类型函数用于判断str
(从start
到end
)的子串是否是回文
bool panlidrome(char *str, long start, long end)
{
if (start >= end)
{
return true;
}
if (!isalpha(str[start]))
{
return panlidrome(str, start + 1, end);
}
if (!isalpha(str[end]))
{
return panlidrome(str, start, end - 1);
}
if (tolower(str[start]) != tolower(str[end]))
{
return false;
}
return panlidrome(str, start + 1, end - 1);
}
main函数,主要是用两个循环来检查输入的所有子串
line
。假设非标准输入/输出功能运行良好。
int main()
{
char *line = cs1010_read_line();
if (line == NULL)
{
return 1;
}
long len = (long)strlen(line) - 1; // -2 to avoid the \n
for (long start = 0; start < len - 2; start += 1)
{
for (long end = start + 2; end < len; end += 1)
{
if (panlidrome(line, start, end))
{
cs1010_println_string("Palindrome");
free(line);
return 0;
}
}
}
cs1010_println_string("Anti-palindrome");
free(line);
}
对于我的问题,我不确定是否会有更优雅的方式,无论是在效率的提升还是代码的整洁方面,来解决这个问题!
谢谢!
如果存在回文子串,则其中心有 2 或 3 个字符的回文子串。 2 个字符的回文子串只是两个相邻的相同字符,而 3 个字符的回文子串只是由另一个字符分隔的两个相同字符。所以算法可以这样:
bool has_palindromic_substring (const char* str)
{
size_t len = strlen(str);
for (size_t i = 0; i < length-1; ++i)
if (str[i] == str[i+1] || str[i] == str[i+2])
return true;
return false;
}