如何在忽略区分大小写和标点符号的情况下检查C中的回文结构?

时间:2015-03-24 16:44:50

标签: c case-sensitive palindrome punctuation

我正在尝试写一个忽略标点符号和区分大小写的回文,1使用数组,第二个使用指针。我的问题是我无法弄清楚如何。代码似乎除此之外还可以正常工作。我还写了一个小写大写的大写字母,但我认为它无论如何都不行。

这是我使用数组的第一个代码。

int is_palindrome1(const char phrase[], int length)
{
  int first = phrase[0];
  int last = phrase[length - 1];

  for (length = 0; phrase[length] != '\0'; length++)
  {
    while (last > first)
    {
      if ((phrase[first]) != (phrase[last]))
      {
        return 0;
      }
      last--;
      first++;
    }
    break;
  }
  return 1;
}

这是我使用指针的第二个回文代码。

int is_palindrome2(const char *phrase, int length)
{
  int i;
  length = strlen(phrase);

  for (i = 0; i < length / 2; i++)
  {
    if (*(phrase + i) != *(phrase + length - i - 1))
    {
      return 0;
    }
  }
  return 1;
}

这是我的小写大写函数。

char lower_to_upper(char lower, char upper)
{
  if (lower >= 'a' && lower <= 'z')
  {
    upper = ('A' + lower - 'a');
    return upper;
  }
  else
  {
    upper = lower;
    return upper;
  }
}

1 个答案:

答案 0 :(得分:5)

因此。让我们分步进行。

最简单的is_palindrome函数:

这看起来与您的代码非常相似。除了您修复的一些语法问题。请注意,se指向字符串的第一个和最后一个字符。

bool is_palindrome(const char *phrase, unsigned length) {
    const char *s = phrase + 0;
    const char *e = phrase + length - 1;

    while (s < e) {
        if (*s != *e)
            return false;
        s += 1;
        e -= 1;
    }
    return true;
}

让我们添加小写/大写比较:

最简单的方法是将所有有效字符转换为大写。看起来你在谈论lower_to_upper()函数时也有这个想法。

唯一的问题是,你的函数有一个非常奇怪的签名(为什么upper是一个参数?)。因此,一个简单的解决方法是使用内置函数toupper()

bool is_palindrome(const char *phrase, unsigned length) {
    const char *s = phrase + 0;
    const char *e = phrase + length - 1;

    while (s < e) {
        if (toupper(*s) != toupper(*e))
            return false;
        s += 1;
        e -= 1;
    }
    return true;
}

那些其他角色(如空格)

现在。最后一部分是你想忽略空格和标点符号。不要用那种方式写字,而是谈谈我们想要比较的字符可能更好。我认为您只想比较字母数字字符。这些是a-z,A-Z和0-9。要测试一个角色是否是其中之一,我们可以构建一个自定义函数,或者我们可以使用内置isalnum()来执行此操作:

bool is_palindrome(const char *phrase, unsigned length) {
    const char *s = phrase + 0;
    const char *e = phrase + length - 1;

    while (s < e) {
        if (!isalnum(*s)) {
            s++;
        } else if (!isalnum(*e)) {
            e--;
        } else if (toupper(*s) == toupper(*e)) {
            s++;
            e--;
        } else {
            return false;
        }
    }
    return true;
}

最后的一些想法:

请注意,在循环的每次传递中,我们移动se或两者都是一步。这确保了我们最终将完成循环。我们s < e的条件也确保一旦我们到达&#34;中间&#34;字符串,我们完成。我把中间放在引号中,因为对于字符串"ab a",中间是第二个字符。

语言是复杂的野兽:

英语在大多数(所有?)系统中都有相当简单的编码。但其他语言并不总是那么简单。在评论中,chux对此有一个建议:

  

一个语言环境可能有多对一的从低到高的映射,反之亦然,如果(tolower(toupper(*s)) != tolower(toupper(*e)))处理它,则使用往返。

我个人并不那么担心,因为我觉得在我们担心这一点的同一点上,我们也应该担心文本是如何编码的。是UTF-8吗?还有别的吗?这可能超出了教师的期望。