# Palindrome Java Program

• Comp Sci

## Homework Statement

Write a method isPalindrome that accepts a string as argument and returns true or false
indicating if the string is a palindrome or not. A palindrome is string that can be read the same way forward and backward. Your method must handle upper and lower case characters (the string “Madam” is a palindrome).

You are not allowed to generate a new string in the your implementation of this method. Rather, you should walk through the string to determine if is a palindrome or not.
Use this method to write a program Palindromes that takes an integer command line argument N followed by N strings and prints the strings that are palindromes.

## The Attempt at a Solution

Code:
public class Palindromes
{
public static void main(String[] args)
{
int N = Integer.parseInt(args[0]);
boolean result;
String str = "";

for (int i = 1; i <= N; i++)
{
str = args[i];
result = isPalindrome(str);
if (result)
System.out.println(str + " is a palindrome.");
else
System.out.println(str + " is not a palindrome.");
}
}

public static boolean isPalindrome(String str)
{
if (str.length() <= 1)
return true;

char right, left;
char c = ' ';
char d = ' ';
int first = 0;
int last = str.length() - 1;

while (c != d)
{
c = str.charAt(first);
right = Character.toLowerCase(c);
d = str.charAt(last);
left = Character.toLowerCase(d);

if (c == d)
{
first++;
last--;
}
else
return false;
}
return true;
}
}

I having trouble figuring out the boolean expression after the while statement. I did most of the code, and hopefully most of it is okay, so any help is appreciated.

Borg
Gold Member
Hiche,

Several things that you should look at:

1. What are the value of c and d the first time they are checked by the while statement? The inside of the while statement will only run if the expression is true. Since they are initialized the same, it won't ever run.

2. Now think about the next pass. Why would you keep checking numbers if c and d aren't equal to each other?

3. Look at the right and left variables. You're assigning values that you never check.

4. You will have to also rethink your logic inside the while statement. A successful palindrome will check numbers, loop back around and will eventually attempt to get characters at a position less than zero and greater than the string length.

Last edited:
Code:
public class Palindromes
{
public static void main(String[] args)
{
int N = Integer.parseInt(args[0]); // parse integer N
boolean result;
String str = "";

for (int i = 1; i <= N; i++)
{
str = args[i];
result = isPalindrome(str);
if (result) // if value returned is true
System.out.println(str + " is a palindrome.");
else
System.out.println(str + " is not a palindrome.");
}
}

public static boolean isPalindrome(String str)
{
if (str.length() <= 1) // a one-character string is always a palindrome
return true;

char right, left;
char c, d;
int first = 0;
int last = str.length() - 1;

while (first < last)
{
c = str.charAt(first);
right = Character.toLowerCase(c);
d = str.charAt(last);
left = Character.toLowerCase(d);

if (right == left)
{
first++;
last--;
}
else
return false;
}
return true;
}
}

Okay, so this worked. It gave me the results I want. Just want to double-check if the code it okay.

Now, I have another relevant question:

Write a method isPalindromePhrase that accepts a string as argument and returns true or false indicating if the string is a palindrome or not. In this version of the method, whitespaces, commas, and apostrophes are ignored. For example, “Lonely Tylenol” and “Madam, I’m Adam” are both palindromes.
The signature of the method should be:
public static boolean isPalindromePhrase(String str)

Again here, you are not allowed to generate a new string in your implementation of this method. Use this method to write a program Palindromes2 that takes an integer command line argument N followed by N strings and prints the strings that are palindromes according to this extended definition.

Do I simply say that if the character is a white-spaces, comma, quotation etc.. then disregard it? How exactly?

Borg
Gold Member
The logic looks a lot better now.
Do I simply say that if the character is a white-spaces, comma, quotation etc.. then disregard it? How exactly?
By checking them for those characters before you do the right == left comparison. It would be the same thing as you're doing if they're equal but just increment/decrement the one that you don't want. You just have to consider the case that the next one (and the one after that, and the one after that, etc.) may also not be wanted.

Okay, so I thought of a couple of methods to implement the second palindrome version:

Code:
while statement <same as above>
{
<same as above>
if (rightChars == ' ' || rightChars == ',')
first++;
else if (leftChars == ' ' || leftChars == ',')
last--;
else if (rightChars == leftChars)
{
first++;
last--;
}
else
return false;

To trace it a bit: say the string is loo..o ol. The first and last characters check and they are equal so both indexes increment and decrement respectively. When reaching the space character (the lastChars reaches it after two loops), the second if statement executes and lastChar is decremented, so the next check will be with firstChars and lastChars - 1, at those particular indexes. Something along those lines..but this is also not working.

Another method that I just thought of was checking whether the character is a space or comma or whatever then remove it and increment/decrement. But I don't know of a way to do that. Is there? I guess not.

And thank you Borg for the help.

Borg
Gold Member
I don't think that's going to work for you. Take a look at what I put in below (you should simplify it). You'll need to do the same for the right and left.

Code:
while (first < last)
{
c = str.charAt(first);
right = Character.toLowerCase(c);
d = str.charAt(last);
left = Character.toLowerCase(d);

// Is the right value disallowed?
// Get next right value
// Is the right value disallowed?
// Get next right value
// Is the right value disallowed?
// Get next right value
// Is the right value disallowed?
// Get next right value

if (right == left)
{
first++;
last--;
}
else
return false;
}

Code:
        if (rightChars == ' ' || rightChars == ',')
rightChars = str.charAt(first++);
if (leftChars == ' ' || leftChars == ',')
leftChars = str.charAt(last--);

Something like this? The logic here seems fine, but it still isn't giving me the correct result. I am hopeless at this so please bear with me.

Borg
Gold Member
Code:
        if (rightChars == ' ' || rightChars == ',')
rightChars = str.charAt(first++);
if (leftChars == ' ' || leftChars == ',')
leftChars = str.charAt(last--);

Something like this? The logic here seems fine, but it still isn't giving me the correct result. I am hopeless at this so please bear with me.
No problem. Let's clean up some of the code to remove some of the confusion. You have just introduced the third set of variables (leftChars and rightChars) to process but you really don't need more than one. One of the nice things about object oriented programming is that you can write statements like this:
left = str.charAt(first);
left = Character.toLowerCase(left);

Or, as one line of code like this:
left = Character.toLowerCase( str.charAt(first) );

Now, instead of creating any new variables, just process the value of left or right. BTW, I modified it to make the left variable process the first character instead of the other way around.

If you have a comma followed by a space, it will fail in most cases, which is probably why it's not working for you. What I was getting at in my previous example is that you will need to put in a couple of loops (see below). Take a look at this and see if you can modify it to get the desired result:
Code:
while (first < last) {
left = str.charAt(first);
left = Character.toLowerCase(left);
right = str.charAt(last);
right = Character.toLowerCase(right);

while ( ????  ) {  // Hint - what is the condition that you're looking for that will make you want to change the left variable?
left =????  // What do you want to do here?  See my previous example.
}

// Do the same thing for the right variable

// There is another change that you need to make here
// Hint - is it an M or an m when it gets here?

if (right == left) {
first++;
last--;
}
else {
return false;
}
}

BTW, don't take my signature as a reflection on yourself. I'm dealing with fools in another part of my life and that quote seemed very appropriate.

The condition is (or should be) that if the characters are spaces, commas, or apostrophes, no? When there is a character not a letter, the left variable should take the next character, hence first should be incremented and the character at that index should be stored in left, no? And vice versa for the right case. I know what to do; the algorithm is clear to me but I'm having a hard time implementing it.

And concerning the last change, didn't we already lower-cased the characters at the beginning?

And another question: there is a method exclusive to characters that checks whether a character is in the range of a to z or A to Z and returns a boolean. Can't we use that? Like:

Code:
if (!Character.isLetter(left)) // if not a letter
// do something here

Borg
Gold Member
The condition is (or should be) that if the characters are spaces, commas, or apostrophes, no? When there is a character not a letter, the left variable should take the next character, hence first should be incremented and the character at that index should be stored in left, no? And vice versa for the right case. I know what to do; the algorithm is clear to me but I'm having a hard time implementing it.
Yes, that is what the condition should be and you are correct on the right case. How are you trying to implement it?
And concerning the last change, didn't we already lower-cased the characters at the beginning?
Are you sure that nothing has changed after it was set to lower case?
And another question: there is a method exclusive to characters that checks whether a character is in the range of a to z or A to Z and returns a boolean. Can't we use that? Like:

Code:
if (!Character.isLetter(left)) // if not a letter
// do something here
Looks reasonable to me.

Figured it out.

Thank you, Borg.

Code:
public class Palindromes2
{
public static void main(String[] args)
{
int N = Integer.parseInt(args[0]); // parse integer N
boolean result;
String str = "";

for (int i = 1; i <= N; i++)
{
str = args[i];
result = isPalindromePhrase(str);
if (result) // if value returned is true (IS palindrome)
System.out.println(str + " is a palindrome.");
else
System.out.println(str + " is not a palindrome.");
}
}

public static boolean isPalindromePhrase(String str)
{
if (str.length() <= 1) // a one-character string is always a palindrome
return true;

char rightChars, leftChars;
int first = 0;
int last = str.length() - 1;

while (first < last)
{
leftChars = str.charAt(first); // characters from the left (moving from left to right)
leftChars = Character.toLowerCase(leftChars);
rightChars = str.charAt(last); // characters from the left (moving from right to left)
rightChars = Character.toLowerCase(rightChars);

while (leftChars == ' ' || leftChars == '\'' || leftChars == ',') // loops over whether the character is a whitespace, comma, or apostrophe
{
leftChars = str.charAt(first++); // get next character
}
while (rightChars == ' ' || rightChars == '\'' || rightChars == ',') // loops over whether the character is a whitespace, comma, or apostrophe
{
rightChars = str.charAt(last--); // get next character
}

leftChars = Character.toLowerCase(leftChars);
rightChars = Character.toLowerCase(rightChars);

if (leftChars == rightChars)
{
first++;
last--;
}
else
return false;
}
return true;
}
}

The entire code. It gave me the results I want. Is this the way you were aiming for, Borg?

Borg