Код не работает с длинными палиндромами

У меня есть задание, над которым я работаю, где я должен взять предложение ввода от пользователя, напечатать слова в обратном порядке, проверить анаграммы и проверить палиндромы. У меня есть функция, работающая для анаграмм, и у меня почти работает моя функция палиндрома. Пока я прошу только два слова, чтобы мои функции работали. Однако по какой-то причине всякий раз, когда я ввожу длинный палиндром (например, гоночный автомобиль или покойник по сравнению с мамой или папой) для обоих слов, которые я запрашиваю, функция палиндрома портится.

Вот код;

#include <stdio.h>
#include <ctype.h> //Included ctype for tolower / toupper functions
#define bool int
#define true 1
#define false 0

//Write boolean function that will check if a word is a palindrome
bool palindrome(char a[])
{
    int c=0;
    char d[80];
    //Convert array into all lower case letters
    while (a[c])
    {
        a[c] = (tolower(a[c]));
        c++;
    }
    c = 0;

    //Read array from end to beginning, store it into another array
    while (a[c])
        c++;

    while(a[c] != 0 && c > -1)
    {
        d[c] = a[c];
        c--;
    }

    c = 0;

    while(a[c])
    {
        printf("%c", d[c]);
        printf("%c", a[c]);
        c++;
    }
    //If two arrays are equal, then they are palindromes
    for(c = 0; a[c] && d[c]; c++)
    {
        while(a[c] && d[c])
        {
        if(a[c] != d[c])
            return false;
        }
    }
    return true;
}

int main(void)
{
    char a[80], b[80];
    bool flagp;
    //Prompt user to enter sentence
    printf("Enter a word: ");
    gets(a);

    flagp = palindrome(a);

    if (flagp)
    {
        printf("\nThe word is a palindrome.");
    }
    else
    {
        printf("\nThe word is not a palindrome.");
    }

    return 0;
}

Это выводит это;

Enter first word: racecar
_r▬a↨c e c a r
The word is not a palindrome.

Однако, если я вхожу в "гоночный автомобиль", он неверно заявляет, что это не палиндром.

Пожалуйста, скажите мне, что я делаю неправильно:'(

2 ответа

Решение
  1. Так a[c] != d[c] верно, когда вы ожидаете, что это будет ложным.
  2. Вы продемонстрировали с вашим printf что это потому что d[c] это мусор.
  3. Это означает, что d не содержит обратной a,
  4. Так что это приводит к проверке следующего фрагмента:

    while(a[c] != 0 && c > -1)
    {
        d[c] = a[c];
        c--;
    }
    

    Он пытается создать перевернутую копию, но совершенно не в состоянии перевернуть что-либо, видя, как он помещает в тот же индекс, что и при взятии.

(Вы сделали первые три шага. Почему вы остановились там?)

Честно говоря, нет причин для d существует вообще. Все это можно сделать на месте.

   +---+---+---+---+---+---+---+
a: | r | a | c | e | c | a | r |
   +---+---+---+---+---+---+---+
     ^                       ^
     |   compare these two   |


         ^               ^
         |  then these   |


                ...

Таким образом, код будет выглядеть так:

size_t len = strlen(a);
if (len) {
   size_t i = 0;
   size_t j = len - 1;
   while (i < j) {
      if (a[i++] != a[j--])
         return 0;
   }
}

return 1;

Заметки:

  1. Пожалуйста, не делай #define true 1 а также #define false 0, Они отличаются от определения C, поэтому вы можете получить неправильный результат, если вы делаете if (b == true) вместо if (b),

  2. c обычно обозначает char, i (а также j а также k) чаще используются для индексов.

Проблема в вашем palindrome функция. Во фрагменте

while(a[c] != 0 && c > -1)
{
    d[c] = a[c];
    c--;
}

ты не меняешься a,

И фрагмент

while (a[c])
    c++;  

причина c выйти из-под контроля 1,

Я исправил эти проблемы. Ваш измененный код:

bool palindrome(char a[])
{
    int c=0;
    char d[80];
    //Convert array into all lower case letters
    while (a[c])
    {
        a[c] = (tolower(a[c]));
        c++;
    }
    c = 0;

    //Read array from end to beginning, store it into another array
    while (a[c])
        c++; 
        c=c-1; // Number of elements in a is one less than that of counter c.

    int i = 0;  // taking another counter for array d
    while(a[c] != 0 && c > -1)
    {
        d[i] = a[c];
        i++;
        c--;
    }
    d[i] = '\n'; // last element of array mut be a nul char
    c = 0;

    while(a[c])
    {
        printf(" %c\t", d[c]);
        printf(" %c\n", a[c]);
        c++;
    }
    //If two arrays are equal, then they are palindromes
    for(c = 0; a[c] && d[c]; c++)
    {

         if(a[c]  != d[c] )
            return false;

    }
    return true;
}  

В конце концов, эта функция недостаточно хороша для проверки палиндрома. Пример:

Входные данные:

I am a     I

ты получишь

The word is not a palindrome.  
Другие вопросы по тегам