Почему моя функция проверки палиндромов всегда возвращает false для палиндромов?

Я пытаюсь проверить, является ли предложение палиндромом или нет. Ни пробел, ни знаки препинания не имеют значения.

Примеры:

• Никогда нечетные или четные

• Мужчина просматривает план Панамского канала.

• Привратник видит имя, гаражник видит бирку с именем

Ни одно из этих предложений не соответствует действительности в моем коде. На моем первом for я стараюсь убрать пробелы, знаки препинания и превратить верхние буквы в нижние.

int palindrome(char *str){
    int n,n2 = 0,i,j=0;
    n = sizeof(str)/sizeof(char);
    char nova[n];

    for (i=0;i< n;i++){
        if(str[i] >= 'A' && str[i] <= 'Z'){
            nova[n2] = ('a' + str[i] - 'A');
            n2++;
        }
        else if(str[i] >= 'a' && str[i] <= 'z'){
            nova[n2] = str[i];
            n2++;
        }
    }

    i=0;
    while (i < n2-1){
        if (nova[i]!= nova[j]){
            return 0;
        }
        i++;
        j--;
    }

    return 1;
}

person Daniel C.    schedule 06.10.2016    source источник
comment
начните с выяснения того, что делает sizeof(str)..   -  person Eugene Sh.    schedule 06.10.2016
comment
Я не могу использовать strlen()   -  person Daniel C.    schedule 06.10.2016
comment
Тогда сделай сам через ходил const char*. В любом случае, sizeof(str) — это не то, что вы используете здесь.   -  person WhozCraig    schedule 06.10.2016
comment
Вы не должны редактировать код в своем вопросе, особенно для удаления строк, на которые указывают люди, например строки sizeof. Я бы рекомендовал отменить ваше редактирование.   -  person Random Davis    schedule 06.10.2016
comment
Я откатил правки. Таким образом, вопрос и существующий ответ менее запутаны. Пожалуйста, задайте новый вопрос, если у вас возникли проблемы с обновленным кодом.   -  person anatolyg    schedule 06.10.2016
comment
@Daniel C.: Просто потому, что вы не можете использовать strlen(), sizeof каким-то волшебным образом не будет работать для ваших целей.   -  person AnT    schedule 06.10.2016
comment
в ваших примерах символы с заглавными буквами должны обрабатываться как соответствующие символы нижнего регистра, но в вопросе это требование не указано. Настоятельно рекомендуем добавить функцию #include <ctype.h> them use the tolower()`, чтобы получить все строчные буквы.   -  person user3629249    schedule 07.10.2016
comment
ПРИМЕЧАНИЕ: выражение: sizeof(str) получает размер указателя. Предложите использовать функцию strlen()   -  person user3629249    schedule 07.10.2016
comment
блок кода, начинающийся с: for (i=0;i< n;i++){, можно сократить до: `for(int i=0; i‹n; i++) { nova[i] = tolower(str[i]; }   -  person user3629249    schedule 07.10.2016


Ответы (3)


Существующий ответ хорош, но есть другой способ решить эту проблему, не используя дополнительную выделенную память. Вам действительно не нужно где-либо хранить буквы, чтобы сравнивать их — вы можете использовать указатели на исходную строку.

int palindrome(char *str)
{
    int i = 0, j = strlen(str);
    while (i < j)
    {
        if (str[j] == '\0' || !isalpha(str[j]))
            --j; // skip the character on the right if it's not a letter
        else if (!isalpha(str[i]))
            ++i; // skip the character on the left if it's not a letter
        else if (tolower(str[i]) != tolower(str[j]))
            return 0; // letters are different? - not a palindrome
    }
    // all letters were equal? - a palindrome
    return 1;
}
person anatolyg    schedule 06.10.2016
comment
Это решение лучше, спасибо. Но я не могу использовать функции, уже определенные в этом случае. - person Daniel C.; 07.10.2016
comment
проблема с этим ответом, пробел будет оцениваться как true при вызове isalpha() - person user3629249; 07.10.2016

строка 4: вы хотите получить количество элементов на sizeof.

Но если вы передадите свои аргументы в функцию по указателю.

  n = sizeof(str)/sizeof(char);

n всегда будет 4 (на 32-битных платформах). Вместо этого используйте

  n = strlen(str)

(нужно #include <string.h>) если это строковый формат в c.

person litao3rd    schedule 06.10.2016

Ок, теперь со всеми доработками работает. Спасибо, парни.

int palindrome(char *str)
{
int n =0,i=0,j;
char nova[100];

while(str[i]!= '\0'){
  if(str[i] >= 'A' && str[i] <= 'Z'){
         nova[n] = ('a' + str[i] - 'A');
         n++;
  }
  else if(str[i] >= 'a' && str[i] <= 'z'){
         nova[n] = str[i];
         n++;
  }
  i++;
}

i=0;
j= n-1;
while (i< j){
    if (nova[i]!= nova[j]){
        return 0;
    }
    i++;
    j--;
}

return 1;
}
person Daniel C.    schedule 06.10.2016
comment
это НЕ работает, когда длина строки превышает 100 символов. - person user3629249; 07.10.2016
comment
Существуют и другие наборы символов, например EBCDIC. В вопросе не указано требование использования набора символов ASCII, поэтому этот ответ не подходит ни для чего, кроме ASCII. - person user3629249; 07.10.2016