1

Is there a way to remove all non alphabet character from a String without regex? I'm trying to check if the String is a palindrome

This is what i tried so far.

    public static boolean isPalindrome( String text )
    {
        int textLength = text.length() - 1;
        String reformattedText = text.trim().toLowerCase();
        for( int i = 0; i <= textLength; i++ )
        {
            if( reformattedText.charAt( i ) != reformattedText.charAt( textLength - i ) )
            {
                return false;
            }
        }

        return true;
    }

But if the input is:

System.out.println( isPalindrome( "Are we not pure? No sir! Panama’s moody"
            + "Noriega brags. It is garbage! Irony dooms a man; a prisoner up to new era." ) );

It should be true.

I'm really having a hard time thinking of how to remove or ignore those non alphabet characters on the String.

newbie
  • 1,884
  • 7
  • 34
  • 55
  • Check char by char and use this http://stackoverflow.com/questions/8248277/how-to-determine-if-a-string-has-non-alphanumeric-characters – mattfetz Feb 03 '15 at 00:32
  • a) what's wrong with a regex? b) You could have two indexes, one advancing from the beginning, one from the end, and have it skip the characters you don't want. – Thilo Feb 03 '15 at 00:32
  • 1
    @Thilo a.) I was asking if there is a way. b.) I was trying to implement that now but also having a hard time. – newbie Feb 03 '15 at 00:37
  • 1
    Simply use a stack and a queue. Iterate over the string, and put each character on the stack and on the queue. Remember to ignore anything that is not a alphabetical. In the end fetch the chars, and compare them :) – Evdzhan Mustafa Feb 03 '15 at 00:45
  • @EvdzhanMustafa am I following you right? 1 loop for iterating the string to put on the stack and a queue then another loop for fetching it and compare them? – newbie Feb 03 '15 at 00:49
  • @newbie Yes, that is correct - maybe not the most efficient solution, but it's quite simple and easy to implement :) – Evdzhan Mustafa Feb 03 '15 at 00:51
  • @EvdzhanMustafa Thats a good idea. Ill do that if i can't find a way to do it in one loop. I can use String instead of stack and queue, do you think its more efficient? – newbie Feb 03 '15 at 00:55

3 Answers3

1

OOPS. Java, not Python.

You can still use list-like access in Java, just a bit more work.

char[] letters = text.toCharArray(); 
int nletters = 0;
for (int i=0; i<letters.length; ++i) {
    if (Character.isLetter(letters[i])
        letters[nletters++] = Character.toUpperCase(letters[i]);
}
// print out letters in array:
System.out.print("letters only: ");
for (int i=0; i<nletters; ++i) {
    System.out.print(letters[i]);
}
System.out.println();

Now use the first nletters positions only in the letters array, since those positions will hold the lowercased letters from the input. An example that just displays the remaining characters is included above.

Now write a loop to compare letters[0] with letters[nletters-1], letters[1] with letters[nletters-2], and so on. If all pairs are equal, you have a palindrome.

Mike Housky
  • 3,959
  • 1
  • 17
  • 31
  • I'm confused on this part _"Now use the first nletters positions only in the letters array, since those positions will hold the lowercased letters from the input."_ – newbie Feb 03 '15 at 01:14
  • @newbie Rather than create a new array, I just moved the letters to the left, as needed. The nletters variable is incremented after each move, so it counts the number of letters seen. These will end up in positions 0 through (nletters-1) in the letters[] array. I'll add an example. – Mike Housky Feb 03 '15 at 12:55
1

I would do something like this:

public static String justAlphaChars(String text) {

    StringBuilder builder = new StringBuilder();

    for (char ch : text.toCharArray()) 
        if (Character.isAlphabetic(ch)) 
            builder.append(ch);

    return builder.toString();
}

Just tested method above in your example bellow and worked. Returned true.

System.out.println( isPalindrome( justAlphaChars ( "Are we not pure? No sir! Panama’s moody"
        + "Noriega brags. It is garbage! Irony dooms a man; a prisoner up to new era." ) ) );
PFROLIM
  • 1,194
  • 9
  • 11
0
String removeNonAlpha(final String word) {
    final StringBuilder result = new StringBuilder();

    for (final char ch : word.toCharArray()) {
        final int ascii = ch;
        if (((ascii >= 65) && (ascii <= 90)) || ((ascii >= 97) && (ascii <= 122))) {
            result.append(ch);
        }
    }
    return result.toString();
}

Explanation: The method will retrieve a string containing only A-Z and a-z characters. I am simply verifying the ascii code for the given char. Please refer to the ASCII code table

  • btw: Just to be clear I am answering the question about removing non alphabet chars without regex... I am not checking if it is a palindrome. :) – William Madruga Feb 03 '15 at 00:55
  • btw why did you use `StringBuilder` instead of just `String`? Is there a reason for it? – newbie Feb 03 '15 at 00:57
  • Strings are final and that means whenever you append something (string + "another") then a new instance of that string is created. Since we're in a loop adding the valid chars to the result string, then use the StringBuilder. – William Madruga Feb 03 '15 at 00:59
  • 1
    It's worth noting this will only work with non-accented characters. If you test the output on `"aħâa"` it would cut out the middle two letters even though they are a-z, and therefore it would be detected as a palindrome. – Andy Brown Feb 03 '15 at 01:06
  • That's true! I'm on a train now, gonna update the code later, thanks Andy! – William Madruga Feb 03 '15 at 01:16
  • I don't have permission to comment on @Mike Housky answer but I would use for-each instead of classical for.... for (final char letter : text.toCharArray()) { ... } – William Madruga Feb 03 '15 at 01:21
  • This method becomes more complex when adding validation for accented letters and it's not worthy anymore to work on :P And I liked the answer using Character class. I should've use it in the first place. :P http://www.theasciicode.com.ar/extended-ascii-code/letter-e-acute-accent-e-acute-lowercase-ascii-code-130.html – William Madruga Feb 03 '15 at 17:15