有没有更优雅的方法来解决这个反回文问题?

问题描述 投票:0回答:1

问题来源:Kattis 的反回文

总结

该问题需要确定给定的文本行是否包含回文(两个或多个字符的子串,向前和向后读相同,忽略空格、标点符号和大小写)。如果存在回文,则输出应为“Palindrome”;否则,输出应该是“Anti-palindrome”。非字母字符必须被忽略,并且大小写差异被视为相同。输入内容至少包含 1 个字母字符,长度最多为 80 个字符。

输入

  1. 输入文本长度:1至80个字符。
  2. 内容:至少一个字母字符,但也可以包含空格、标点符号和其他非字母字符。

输出

  • “Palindrome”如果文本包含任何回文(至少 2 个字母字符的子字符串,在忽略非字母字符和大小写后为回文)。
  • “反回文”如果不存在这样的回文。

我的解决方案

潘林德罗姆()

这个

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);
}

对于我的问题,我不确定是否会有更优雅的方式,无论是在效率的提升还是代码的整洁方面,来解决这个问题!

谢谢!

algorithm palindrome
1个回答
0
投票

如果存在回文子串,则其中心有 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;
}
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.