Так. Давайте сделаем это по шагам.
Простейшая функция is_palindrome:
Это будет очень похоже на ваш код. За исключением того, что некоторые проблемы с синтаксисом, которые у вас есть, исправлены. Обратите внимание, что s
и e
указывают на первый и последний символ строки.
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;
}
Как насчет этих других символов (например, пробелов)
В настоящее время. Последняя часть заключается в том, что вы хотите игнорировать пробелы и знаки препинания. Вместо того, чтобы формулировать это таким образом, было бы лучше поговорить о персонажах, которые мы действительно хотим сравнить. Я думаю, что вы хотите сравнивать только буквенно-цифровые символы. Это az, AZ и 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;
}
Некоторые заключительные мысли:
Обратите внимание, что при каждом проходе цикла мы перемещаем s
, e
или оба на один шаг. Это гарантирует, что мы в конечном итоге завершим цикл. Наше условие s < e
также гарантирует, что как только мы достигнем «середины» строки, мы закончим. Я взял середину в кавычки, потому что для строки "ab a"
середина — это второй символ.
Языки - сложные звери:
Английский язык имеет довольно простую кодировку в большинстве (во всех?) системах. Но другие языки не всегда так просты. В комментарии chux была рекомендация по этому поводу:
Локаль, которая может иметь сопоставление «многие к 1» от нижнего к верхнему или наоборот, с использованием кругового пути, если (tolower(toupper(*s)) != tolower(toupper(*e)))
обрабатывает это.
Я лично не так обеспокоен, потому что я чувствую, что примерно в тот же момент, когда мы беспокоимся об этом, мы также должны беспокоиться о том, как кодируется текст. Это UTF-8? Это что-то другое? Вероятно, это превосходит ожидания ваших инструкторов.
person
Bill Lynch
schedule
24.03.2015
'A' + lower - 'a'
, выполняющемся для символов, вы, вероятно, получите переполнение при вычислении промежуточных результатов. - person Eugene Sh.   schedule 24.03.2015int first = phrase[0]; int last = phrase[length - 1];
ошибаются. - person BLUEPIXY   schedule 24.03.2015ctype
int toupper(int c);
- person Weather Vane   schedule 24.03.2015'A'
являетсяint
. - person chux - Reinstate Monica   schedule 24.03.2015'A' + lower
будет повышен доint
. - person Bill Lynch   schedule 25.03.2015