Игнорирование регистра и небуквенных символов при проверке палиндрома
На предыдущем этапе наш проверятель палиндромов работал для простых строк, таких как "madam" и "racecar". Однако в реальной жизни палиндромы часто игнорируют регистр букв и пунктуацию. Например, "A man, a plan, a canal: Panama" считается палиндромом.
На этом этапе мы усовершенствуем нашу программу PalindromeChecker
, чтобы она обрабатывала такие случаи, игнорируя небуквенные символы и воспринимая заглавные и строчные буквы одинаково.
Откройте файл PalindromeChecker.java
в редакторе WebIDE. Мы изменим метод checkPalindrome
.
Замените существующий метод checkPalindrome
на следующую обновленную версию:
// Method to check if a string is a palindrome using two pointers,
// ignoring case and non-letter characters
public static boolean checkPalindrome(String str) {
// Initialize two pointers
int left = 0; // Pointer starting from the beginning
int right = str.length() - 1; // Pointer starting from the end
// Loop while the left pointer is less than the right pointer
while (left < right) {
// Move left pointer past non-letter characters
while (left < right && !Character.isLetter(str.charAt(left))) {
left++;
}
// Move right pointer past non-letter characters
while (left < right && !Character.isLetter(str.charAt(right))) {
right--;
}
// If left and right pointers haven't crossed and characters don't match (ignoring case)
if (left < right && Character.toLowerCase(str.charAt(left)) != Character.toLowerCase(str.charAt(right))) {
// If characters don't match, it's not a palindrome
return false;
}
// Move the pointers inwards
left++;
right--;
}
// If the loop completes without finding any mismatch, it's a palindrome
return true;
}
Вот какие изменения мы внесли:
- Мы добавили два цикла
while
внутри основного цикла while (left < right)
.
- Первый вложенный цикл
while
(while (left < right && !Character.isLetter(str.charAt(left)))
) перемещает указатель left
вперед, пока он все еще находится слева от указателя right
и символ в позиции left
не является буквой (!Character.isLetter(...)
).
- Второй вложенный цикл
while
(while (left < right && !Character.isLetter(str.charAt(right)))
) перемещает указатель right
назад, пока он все еще находится слева от указателя right
и символ в позиции right
не является буквой.
- Сравнение
if (left < right && Character.toLowerCase(str.charAt(left)) != Character.toLowerCase(str.charAt(right)))
теперь включает два важных условия:
left < right
: Это гарантирует, что мы сравниваем символы только в том случае, если указатели не пересеклись после пропуска небуквенных символов.
Character.toLowerCase(...)
: Это преобразует оба символа в нижний регистр перед сравнением, фактически игнорируя регистр.
- Если символы (после преобразования в нижний регистр) не совпадают, мы возвращаем
false
.
- Если они совпадают, мы перемещаем оба указателя внутрь (
left++
, right--
), чтобы проверить следующую пару символов.
Теперь изменим метод main
, чтобы проверить программу на строке, содержащей пробелы, пунктуацию и смешанный регистр. Замените существующие тестовые случаи в методе main
на следующие:
public static void main(String[] args) {
String testString = "A man, a plan, a canal: Panama"; // A classic palindrome
boolean isPalindrome = checkPalindrome(testString);
if (isPalindrome) {
System.out.println("\"" + testString + "\" is a palindrome.");
} else {
System.out.println("\"" + testString + "\" is not a palindrome.");
}
testString = "No 'x' in Nixon"; // Another palindrome
isPalindrome = checkPalindrome(testString);
if (isPalindrome) {
System.out.println("\"" + testString + "\" is a palindrome.");
} else {
System.out.println("\"" + testString + "\" is not a palindrome.");
}
testString = "hello world"; // Not a palindrome
isPalindrome = checkPalindrome(testString);
if (isPalindrome) {
System.out.println("\"" + testString + "\" is a palindrome.");
} else {
System.out.println("\"" + testString + "\" is not a palindrome.");
}
}
Сохраните файл PalindromeChecker.java
.
Скомпилируйте и запустите обновленную программу в терминале:
javac PalindromeChecker.java
java PalindromeChecker
Теперь вы должны увидеть следующий вывод, правильно определяющий палиндромы даже с небуквенными символами и смешанным регистром:
"A man, a plan, a canal: Panama" is a palindrome.
"No 'x' in Nixon" is a palindrome.
"hello world" is not a palindrome.
Вы успешно усовершенствовали свой проверятель палиндромов для обработки более сложных строк!