Ignorar Maiúsculas/Minúsculas e Caracteres Não-Letras em Palíndromos
Na etapa anterior, nosso verificador de palíndromos funcionava para strings simples como "madam" e "racecar". No entanto, palíndromos do mundo real geralmente ignoram a capitalização e a pontuação. Por exemplo, "A man, a plan, a canal: Panama" é considerado um palíndromo.
Nesta etapa, aprimoraremos nosso PalindromeChecker para lidar com esses casos, ignorando caracteres que não são letras e tratando letras maiúsculas e minúsculas da mesma forma.
Abra o arquivo PalindromeChecker.java no editor WebIDE. Modificaremos o método checkPalindrome.
Substitua o método checkPalindrome existente pela seguinte versão atualizada:
// 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;
}
Aqui estão as alterações que fizemos:
- Adicionamos dois loops
while dentro do loop principal while (left < right).
- O primeiro loop
while interno (while (left < right && !Character.isLetter(str.charAt(left)))) move o ponteiro left para frente, desde que ainda esteja à esquerda do ponteiro right e o caractere no ponteiro left não seja uma letra (!Character.isLetter(...)).
- O segundo loop
while interno (while (left < right && !Character.isLetter(str.charAt(right)))) move o ponteiro right para trás, desde que ainda esteja à esquerda do ponteiro right e o caractere no ponteiro right não seja uma letra.
- A comparação
if (left < right && Character.toLowerCase(str.charAt(left)) != Character.toLowerCase(str.charAt(right))) agora inclui duas verificações importantes:
left < right: Isso garante que comparemos os caracteres somente se os ponteiros não tiverem se cruzado após ignorar não-letras.
Character.toLowerCase(...): Isso converte ambos os caracteres para minúsculas antes de compará-los, ignorando efetivamente a capitalização.
- Se os caracteres (após a conversão para minúsculas) não corresponderem, retornamos
false.
- Se eles corresponderem, movemos ambos os ponteiros para dentro (
left++, right--) para verificar o próximo par de caracteres.
Agora, vamos modificar o método main para testar com uma string que inclui espaços, pontuação e capitalização mista. Substitua os casos de teste existentes no método main por isto:
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.");
}
}
Salve o arquivo PalindromeChecker.java.
Compile e execute o programa atualizado no Terminal:
javac PalindromeChecker.java
java PalindromeChecker
Você deve ver a seguinte saída, identificando corretamente os palíndromos, mesmo com caracteres que não são letras e capitalização mista:
"A man, a plan, a canal: Panama" is a palindrome.
"No 'x' in Nixon" is a palindrome.
"hello world" is not a palindrome.
Você aprimorou com sucesso seu verificador de palíndromos para lidar com strings mais complexas!