0

I have been assigned to complete a palindrome program. However, I cannot use the charAt method.

Typically, I'd be able to solve this fairly quickly. However, since I cannot use charAt, I have no clue as to how I should go about doing this.

My idea is to take the length of the string, divide it by two (however this limits me to strings only with an even number of chars) then convert the substrings into int's and then finally compare the two int's.

This is my code thus far-

public static boolean isPal(String s)
{
    int length = s.length();
    int math = length / 2;
    String side1 = s.substring(1,math);
    String side2 = s.substring(math, length);

    int s1 = Integer.parseInt(side1);
    int s2 = Integer.parseInt(side2);

    if(s1 == s2){
        return true;
    } else {
        return false;
    }
}

However, I have realized that this might not, and probably is not, the best way to handle the situation. I am currently running into this error-

Exception in thread "main" java.lang.NumberFormatException: For input string: "i"
at java.lang.NumberFormatException.forInputString(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at Palindrome.isPal(Lab08st.java:47)
at Lab08st.main(Lab08st.java:20)

I believe it is because I need a for loop of sorts. However, having inadequate Java experience, I am unsure.

I am open to any and all suggestions. (So long as they do not require charAt)

Kultid_Games
  • 311
  • 1
  • 3
  • 10
  • 1
    It's a bit cheeky, but maybe use `s.toCharArray()[i]`? – Mshnik Jan 23 '15 at 18:01
  • 5
    are you allowed to use `reverse()`? – genisage Jan 23 '15 at 18:02
  • 1
    Doesn't this only work for integers because of `Integer.parseInt(side1);`? I would use a `StringBuilder` and shorten the function to `return new StringBuilder(s).reverse().toString().equals(s);` –  Jan 23 '15 at 18:04

4 Answers4

0

Use this:

public static boolean isPal(String s) {
    char[] chars = s.toCharArray();
    int len = chars.length;

    for (int i = 0; i < len ; i++) {
        if(chars[i] != chars[len-i-1] ){
            return false;
        }
    }
    return true;
 }
sparrow
  • 450
  • 5
  • 13
  • Sparrow- Thank you, I believe I have figured it out by myself actually, but when in doubt, I'll try this! To Erst, again, I am sincerely grateful that you have morality, however, it is not necessary in this situation. You assumed that it was homework, which it is not. – Kultid_Games Jan 26 '15 at 00:52
0

Your approach is flawed in several ways:

  • Integer.parseInt(String) only works on optionally-signed digit strings that represent base-10 numbers representable as type int. Your function will utterly fail on non-numeric inputs, and on inputs that are too large for the halves to be represented as ints (some 19-20-character inputs; all longer inputs).
  • Your function will fail on any input having an odd number of characters, because you cannot split such inputs evenly into halves.
  • Your logic is flawed anyway. It would judge "1010" a palindrome (which it isn't), and it would judge "1001" not a palindrome (though it is one).

You can pick out the input String's characters one-by-one via a variety of techniques, among them:

  • You can get the characters in a char[] via String.toCharArray(), as has elsewhere been suggested.
  • You can consume the input via a series of substring() invocations.
  • You can use a StringCharacterIterator to iterate over the characters

Since it's not clear why you are not permitted to use charAt(), here's an approach that altogether avoids relying on indexing:

import java.text.StringCharacterIterator;

// ...

public static boolean isPal(String s)
{
    StringCharacterIterator it = new StringCharacterIterator(s);
    String reversed = ""

    for (char c = it.first(); c != CharacterIterator.DONE; c = it.next()) {
        reversed = c + reversed;
    }

    return reversed.equals(s);
}

There are more efficient approaches, but that one is clear and simple.

Or here's one that doesn't rely (explicitly) on any classes other then String, but does use the indexes 0 and 1:

public static boolean isPal(String s)
{
    String tail = s;
    String reversed = ""

    while (tail.length() > 0) {
        reversed = tail.substring(0, 1) + reversed;
        tail = tail.substring(1);
    }

    return reversed.equals(s);
}

Or since you had the idea of splitting the String into two, perhaps that was directed by your instructor? Are you perhaps studying recursion? Because you can also reverse the input string via a recursive algorithm: (1) split the string in two (as evenly as possible works best); (2) recursively reverse each half; (3) put the reversed halves back together in the opposite order. (Implementation left as an exercise.)

With all that said, do note that Reticality's one-liner using StringBuilder.reverse() is better on all counts if it satisfies the requirements.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157
0

My Solution-

import java.util.*;
public class MyClass {
    public static void main(String args[]) {
      
      String str = "pappap";
      String sp = str.toLowerCase();
      char[] ch = sp.toCharArray();
      int len = ch.length;
      int lastIndex = ch.length-1;
      int count = 1;
      int first = 0;
      int last = sp.length()-1;
     for(; first < last  ;){  
              if(ch[first] == ch[last] ){
                  first= first+1;
                  last= last-1; 
               }
             else{
              count = 0;
              break;
              }
      }
      
    String result = (count == 1) ?  "Palindrome" : "Not a palindrome " ;
    System.out.println(result);
}
}
Tyr
  • 11
  • 1
-1

If you are checking to see if a number, given to you as a string, is a palindrome, then you might use math to do it. Use an algorithm that compares the least significant with the most significant digit, then remove those to digits and continue. If there are an odd number of digits then you don't need to compare that middle digit with anything -- you just need the number of digits / 2 steps.

This code left as an exercise because it is homework.

ErstwhileIII
  • 4,829
  • 2
  • 23
  • 37
  • The error reported in the question seems to indicate that the input is not guaranteed to be numeric. – John Bollinger Jan 23 '15 at 18:42
  • ".... convert the substrings into ints ..." was what I took my clue from. We can wait till we here from the questioner – ErstwhileIII Jan 23 '15 at 18:53
  • I understand, but "[...]NumberFormatException: For input string: "i"" certainly seems to indicate that "i" is expected to be an allowed input. – John Bollinger Jan 23 '15 at 18:56
  • Apologies! I hadn't been around a computer until just now. Pertaining to your answer, that would be a more logical way of going about it. I'll look into and I thank you for that. As to the "spirit of the homework", I should not have said assigned, as this was classwork that I failed to complete. Obviously, being a grade-freak, I had to learn how to do this so, I decided to check here and see how I could go about this. (You guys know your stuff!) I would also like to be noted that it **should** not be of your concern whether it is homework or not. However, I thank you for doing so. – Kultid_Games Jan 26 '15 at 00:38