java.lang.StringIndexOutOfBoundsException:字符串索引超出范围:-1(与另一个程序一起使用)

时间:2016-11-07 22:52:47

标签: java string

我应该创建一个程序,找到DNA串中最长的回文。与普通的回文程序不同,这个要求A匹配T和C以匹配G(因此代替1221,我们有TCGA)。在尝试自己之后,我确实找到了一个非常好的程序来解决正常的回文问题,这个问题就在这个网站上: http://www.journaldev.com/530/java-program-to-find-out-longest-palindrome-in-a-string

然后我尝试修改它以满足我的需要。基本上我所做的改变如下:

  1. 我从参数行中读取了一个字符串,而不是示例中显示的那些字符串。该字符串是以下DNA序列(虽然我只测试了部分程序):
  2. http://introcs.cs.princeton.edu/java/31datatype/genomeVirus.txt

    1. 而不是命令

       while (left >= 0 && right < s.length()
                  && s.charAt(left) == s.charAt(right)) {
              left--;
              right++;
          }
      
    2. 我做了:

      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++;
      

      (下面的完整代码)

      然而,当我在一个字符串上尝试这个程序时,我总是得到错误:

      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)
      

      我只是不明白!我没有意识到我是如何摆脱字符串的,当我尝试连接的原始程序时,无论哪个字符串都可以使用。我觉得我正在做所有事情,只需用各种有意义的场景替换==命令。

      我认为它可能与

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

      我试图取消+1,但它似乎毁了整个交易。我只是没有意识到我是如何走出弦乐的,因为它在调整之前完美无缺。

      任何帮助将不胜感激!以下是代码!

      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;
       }
      
      }
      

1 个答案:

答案 0 :(得分:2)

  1. 您正在使用right == 0进行调用。您需要将第一个呼叫更改为:

     String palindrome = intermediatePalindrome(s, i, i+1)
    
  2. 运营商优先级问题。你添加了一些||即使范围检查失败也会评估的条件。它应该是:

    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'))
    
  3. 请注意第二个&amp;&amp;。

    的整个第二个操作数的括号