1

I'm working on a program for Java on how to find a list of palindromes that are embedded in a word list file. I'm in an intro to Java class so any sort of help or guidance will be greatly appreciated!

Here is the code I have so far:

import java.util.Scanner;
import java.io.File;

class Palindromes {

    public static void main(String[] args) throws Exception {
        String pathname = "/users/abrick/resources/american-english-insane";
        File dictionary = new File(pathname);
        Scanner reader = new Scanner(dictionary);
        while (reader.hasNext()) {
            String word = reader.nextLine();
            for (int i = 0; i > word.length(); i++) {
                if (word.charAt(word.indexOf(i) == word.charAt(word.indexOf(i)) - 1) {
                    System.out.println(word);
                }
            }
        }
    }
}

There are 3 words that are 7 letters or longer in the list that I am importing.

Makoto
  • 104,088
  • 27
  • 192
  • 230
user2255502
  • 19
  • 1
  • 2
  • 2
    Is there one word per line? – ryaanwells Apr 14 '13 at 22:53
  • 1
    OK, so do you understand what the condition in that `if` statement does? If not, read it again and see if it does what you want to. You seem to check each character with itself. – asgs Apr 14 '13 at 22:55
  • Hint: For each word of length N, you only need to loop N / 2 times. – Greg Case Apr 14 '13 at 22:57
  • See also: http://stackoverflow.com/questions/4138827/check-string-for-palindrome/4139065#4139065 – Piccolo Apr 14 '13 at 23:12
  • Thanks asgs I didn't realize that when reading it over – user2255502 Apr 14 '13 at 23:12
  • One problem is with the `indexOf` calls, inside your `if` statement. These calls find the position of a particular character, within a string. But the arguments that your passing to `indexOf` are not characters. You shouldn't need `indexOf` at all to solve this problem, only `charAt`. Another problem is that you have > instead of < in your `for` statement. – Dawood ibn Kareem Apr 14 '13 at 23:45

4 Answers4

1

You have a few ways to solve this problem.

A word is considered a palindrome if:

  • It can be read the same way backwards as forwards.
  • The first element is the same as the last element, up until we reach the middle.
  • Half of the word is the same as the other half, reversed.
  • A word of length 1 is trivially a palindrome.

Ultimately, your method isn't doing much of that. In fact, you're not doing any validation at all - you're only printing the word if the first and last character match.

Here's a proposal: Let's read each end of the String, and see if it's a palindrome. We have to take into account the case that it could potentially be empty, or be of length 1. We also want to get rid of any white space in the string, as that can cause errors on validation - we use replaceAll("\\s", "") to solve that.

 public boolean isPalindrome(String theString) {
    if(theString.length() == 0) {
        throw new IllegalStateException("I wouldn't expect a word to be zero-length");
    }
    if(theString.length() == 1) {
        return true;
    } else {
        char[] wordArr = theString.replaceAll("\\s", "").toLowerCase().toCharArray();
        for(int i = 0, j = wordArr.length - 1; i < wordArr.length / 2; i++, j--) {
            if(wordArr[i] != wordArr[j]) {
                return false;
            }
        }
        return true;
    }
}
Makoto
  • 104,088
  • 27
  • 192
  • 230
0

Since this is homework, i'll not supply you with code.

When i code, the first thing i do is take a step back and ask myself,

"what am i trying to get the computer to do that i would do myself?"

Ok, so you've got this huuuuge string. Probably something like this: "lkasjdfkajsdf adda aksdjfkasdjf ghhg kajsdfkajsdf oopoo"

etc..

A string's length will either be odd or even. So, first, check that.

The odd/even will be used to figure out how many letters to read in.

If the word is odd, read in ((length-1)/2) characters.

if even (length/2) characters.

Then, compare those characters to the last characters. Notice that you'll need to skip the middle character for an odd-lengthed string. Instead of what you have above, which checks the 1st and 2nd, then 2nd and 3rd, then 3rd and fourth characters, check from the front and back inwards, like so.

        while (reader.hasNext()) {
        String word = reader.nextLine();
          boolean checker = true;

        for (int i = 0; i < word.length(); i++) {
              if(word.length()<2){return;}
            if (word.charAt(i) != word.charAt(word.length()-i)  {
               checker = false;
            }

        }
        if(checker == true)
          {System.out.println(word);}
        }
FuriousFolder
  • 1,200
  • 1
  • 12
  • 27
  • The length isn't the issue I'm having. Each word in the file has its own line in the file. I know I'm on the right track and the program is compiling. I'm just not receiving any input. I'm not asking for any answers or code, but if you could point me more in the right direction of where I'm going wrong with my code, I would really appreciate it – user2255502 Apr 14 '13 at 23:08
  • Your if statement is going to throw an exception since word.length-i will be word.length - 0 the first time around and that would result in a StringIndexOutOfBoundsException – Nico Apr 14 '13 at 23:36
  • I assumed the individual implementing the method would recognize that. Thank you for bringing that to my attention. – FuriousFolder Apr 15 '13 at 03:11
0

I'm assuming that you're reading in strings. Use string.toCharArray() to convert each string to a char[]. Iterate through the character array using a for loop as follows: on iteration 1, if the first character is equal to the last character, then proceed to the next iteration, else return false. On iteration 2, if the second character is equal to the second-to-last character then proceed to the next iteration, else return false. And so on, until you reach the middle of the string, at which point you return true. Be careful of off-by-one errors; some strings will have an even length, some will have an odd length.

If your palindrome checker is case insensitive, then use string.toLowerCase().toCharArray() to preprocess the character array.

You can use string.charAt(i) instead of string.toCharArray() in the for loop; in this case, if the palindrome checker is case insensitive then preprocess the string with string = string.toLowerCase()

Zim-Zam O'Pootertoot
  • 17,888
  • 4
  • 41
  • 69
  • The checker is not case sensitive and I know I'm able to store each word as a string and loop it to check for the palindrome. My issue is with while and if statements apparently – user2255502 Apr 14 '13 at 23:11
0

Let's break the problem down: In the end, you are checking if the reverse of the word is equal to the word. I'm going to assume you have all of the words stored in an array called wordArray[].

I have some code for getting the reverse of the word (copied from here):

public String reverse(String str) {
  if ((null == str) || (str.length() <= 1)) {
    return str;
  }
  return new StringBuffer(str).reverse().toString();
}

So, now we just need to call that on every word. So:

for(int count = 0; count<wordArray.length;count++) {
  String currentWord = wordArray[count];
  if(currentWord.equals(reverse(currentWord)) {
    //it's a palendrome, do something
  }
}
Piccolo
  • 1,612
  • 4
  • 22
  • 38
  • Each word has its own line and each word is stored in a string. We did something similar in class by just storing each word in a string rather than an array. – user2255502 Apr 14 '13 at 23:05
  • @user2255502 `if ([your variable].equals(reverse([your variable])) {[do something]}` or `String wordArray[] = {[your variable 1], [your variable 2], [etc]};` – Piccolo Apr 14 '13 at 23:08