0

I'm supposed to create a program that finds the longest palindrome in a DNA string. Unlike a regular palindrome program, this one requires A to match with T and C to match with G (so instead of 1221 we'd have TCGA for example). After trying myself I did find a very good program for the normal palindrome problem, the one on this website: http://www.journaldev.com/530/java-program-to-find-out-longest-palindrome-in-a-string

I then tried to modify it to fit my needs. Basically the changes I made were the following:

  1. Instead of those strings shown in the example, I read a string from the argument line. The string is the following DNA sequence (although I tested the program with only parts of it):

http://introcs.cs.princeton.edu/java/31datatype/genomeVirus.txt

  1. Instead of the command

     while (left >= 0 && right < s.length()
                && s.charAt(left) == s.charAt(right)) {
            left--;
            right++;
        }
    

I did:

while (left >= 0 && right < s.length()
&& s.charAt(left) == 'A' && s.charAt(right) == 'T' || s.charAt(left) == 'T' && s.charAt(right) == 'A'
|| s.charAt(left) == 'G' && s.charAt(right) == 'C' || s.charAt(left) == 'C' && s.charAt(right) == 'G')
   {
 left--;
 right++;

(Full code below)

However, when I try this program on a string, I always get the error:

java.lang.StringIndexOutOfBoundsException: String index out of range: -1
    at java.lang.String.substring(Unknown Source)
    at LongestPalindrome.intermediatePalindrome(LongestPalindrome.java:17)
    at LongestPalindrome.longestPalindromeString(LongestPalindrome.java:26)
    at LongestPalindrome.main(LongestPalindrome.java:5)

I just don't get it! I don't realize how I'm getting out of the string, when I try the original program I linked to, it always works with no matter which string. I feel like I'm doing everything correctly, simply replacing the == command with various scenarios that should make sense.

I figured it might have something to do with

return s.substring(left+1, right);"

I tried to take the +1 away but it seems to ruin the whole deal. I just don't realize how I'm going out of the string, since it worked perfectly before my adjustments.

Any help would be greatly appreciated! Below is the code!

public class LongestPalindrome {

 public static void main(String[] args) {
   String gen = new String(args[0]);
   System.out.println(longestPalindromeString(gen));
 }

 static public String intermediatePalindrome(String s, int left, int right)     {
  if (left > right) return null;
  while (left >= 0 && right < s.length()
    && s.charAt(left) == 'A' && s.charAt(right) == 'T' || s.charAt(left) == 'T' && s.charAt(right) == 'A'
|| s.charAt(left) == 'G' && s.charAt(right) == 'C' || s.charAt(left) == 'C' && s.charAt(right) == 'G')
       {
   left--;
   right++;
  }
  return s.substring(left+1, right);
 }

 // O(n^2)
 public static String longestPalindromeString(String s) {
  if (s == null) return null;
  String longest = s.substring(0, 1);
  for (int i = 0; i < s.length() - 1; i++) {
   //odd cases like 121
   String palindrome = intermediatePalindrome(s, i, i);
    if (palindrome.length() > longest.length()) {
    longest = palindrome;
   }
   //even cases like 1221
   palindrome = intermediatePalindrome(s, i, i + 1);
   if (palindrome.length() > longest.length()) {
    longest = palindrome;
   }
  }
  return longest;
 }

}
12
  • What input string are you giving it when it fails? Commented Nov 7, 2016 at 22:53
  • 1
    BTW: in String gen = new String(args[0]);, the new String isn't necessary. String gen = args[0]; is sufficient. Commented Nov 7, 2016 at 22:54
  • Coincidence. Similar question was just asked with Python tag... Commented Nov 7, 2016 at 22:57
  • 1
    && is evaluated before ||, so the shortcut does not happen, and the index out of bounds happens. put your comparison condition in parenthesis Commented Nov 7, 2016 at 22:59
  • 1
    (basically if left == -1, s.charAt(left) == 'T' is still executed) Commented Nov 7, 2016 at 23:00

1 Answer 1

2
  1. You are calling it with right == 0. You need to change the first call to:

     String palindrome = intermediatePalindrome(s, i, i+1)
    
  2. Operator precedence problem. You've added some || conditions which are also evaluated even if the range checks fail. It should be:

    while (left >= 0 && right < s.length()
    && (s.charAt(left) == 'A' && s.charAt(right) == 'T'
        || s.charAt(left) == 'T' && s.charAt(right) == 'A'
        || s.charAt(left) == 'G' && s.charAt(right) == 'C'
        || s.charAt(left) == 'C' && s.charAt(right) == 'G'))
    

Note the parentheses around the entire second operand of the second &&.

Sign up to request clarification or add additional context in comments.

6 Comments

Thanks a lot for the quick response. I did try to change the parentheses but the problem persisted, so I went back to the way they were originally. But even if you're right, I still get the same error with the parentheses modified as you did them, which is a shame.
It looks like you edited your response although I'm not sure. Again, thanks a lot but it still didn't work unfortunately. Did it work when you ran it? Again, I really appreciate your help, I don't know why the problem persists (I'm using DrJava like a noob, but same error occurs in Java Visualizer).
I only reformatted, no code change. You must have not copied it correctly.
Oh right, I'm sorry. Anyways, I tried it with your code and I still got the error, unfortunately. Thanks for the tip though!
I swear, I've tried it so many times. The only change I've made to my code is to put your while loop instead of the original. I've copied it numerous times.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.