Код не работает с длинными палиндромами
У меня есть задание, над которым я работаю, где я должен взять предложение ввода от пользователя, напечатать слова в обратном порядке, проверить анаграммы и проверить палиндромы. У меня есть функция, работающая для анаграмм, и у меня почти работает моя функция палиндрома. Пока я прошу только два слова, чтобы мои функции работали. Однако по какой-то причине всякий раз, когда я ввожу длинный палиндром (например, гоночный автомобиль или покойник по сравнению с мамой или папой) для обоих слов, которые я запрашиваю, функция палиндрома портится.
Вот код;
#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 ответа
- Так
a[c] != d[c]
верно, когда вы ожидаете, что это будет ложным. - Вы продемонстрировали с вашим
printf
что это потому чтоd[c]
это мусор. - Это означает, что
d
не содержит обратнойa
, Так что это приводит к проверке следующего фрагмента:
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;
Заметки:
Пожалуйста, не делай
#define true 1
а также#define false 0
, Они отличаются от определения C, поэтому вы можете получить неправильный результат, если вы делаетеif (b == true)
вместоif (b)
,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.