【问题标题】:LastIndexOf and java.lang.IndexOutOfBoundsExceptionLastIndexOf 和 java.lang.IndexOutOfBoundsException
【发布时间】:2018-07-03 13:32:33
【问题描述】:

我有一个字符串CCAATA CCGT,我正在尝试获取连续子序列的固定长度n。然后,我想得到这样的东西:

该字符串中每个子序列的索引。 0-3、1-4、2-5等

0 thru 3 : CCAA 
1 thru 4 : CAAT 
2 thru 5 : AATA 
3 thru 6 : ATAC 
4 thru 7 : TACC 
5 thru 8 : ACCG 
6 thru 9 : CCGT 

列表大小为 7。在这里,我循环遍历列表并获取索引和 lastIndexOf。之后,3 thru 6 : ATAC,我得到了

线程“main”中的异常 java.lang.IndexOutOfBoundsException:索引:7,大小:7

for (int i = 0; i < list.size(); i++) {
            System.out.println(ss.indexOf(list.get(i)) 
             + " thru " + ss.lastIndexOf(list.get(i + n - 1)) + " : " 
            + list.get(i));

演示:

import java.util.ArrayList;

public class Subsequences {

    public static void main(String[] args) {

        String s = "CCAATA CCGT";
        ArrayList<String> list = new ArrayList<String>(); // list of subsequence

        int n = 4; // subsequences of length

        String ss = s.replaceAll("\\s+", "");
        String substr = null;

        for (int i = 0; i <= ss.length() - n; i++) {
            substr = ss.substring(i, i + n);
            list.add(substr);
        }

        for (int i = 0; i < list.size(); i++) {
            System.out.println(ss.indexOf(list.get(i)) 
             + " thru " + ss.lastIndexOf(list.get(i + n - 1)) + " : " 
            + list.get(i));

        }
    }
}

有什么提示吗?

【问题讨论】:

    标签: java string arraylist


    【解决方案1】:

    您也可以使用简单的正则表达式来做到这一点。删除空格并运行此正则表达式:

    (?=(.{4}))
    

    示例:

    package com.see;
    
    import java.util.ArrayList;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    public class RegexTest {
    
        private static final String TEST_STR = "CCAATA CCGT";
    
        public ArrayList<String> getMatchedStrings(String input) {
            ArrayList<String> matches = new ArrayList<String>();
            input = input.replaceAll("\\s", "");
    
            Pattern pattern = Pattern.compile("(?=(.{4}))");
            Matcher matcher = pattern.matcher(input);
    
            while (matcher.find())
                matches.add(matcher.group(1));
    
            return matches;
        }
    
        public static void main(String[] args) {
            RegexTest rt = new RegexTest();
            for (String string : rt.getMatchedStrings(TEST_STR)) {
                System.out.println(string);
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

      在你的循环中

      for (int i = 0; i < list.size(); i++) { 
         System.out.println(ss.indexOf(list.get(i)) 
         + " thru " + ss.lastIndexOf(list.get(i + n - 1))
         + " : " + list.get(i));
      }
      

      当您执行list.get(i + n - 1) 并且您的i 为 4 时,上瘾的结果将是 4 + 4 - 1 = 7,并且您无法获得与您的索引相同或更大的列表成员list.size(),所以系统抛出异常

      要获得您期望的结果,您可以执行以下操作:

      import java.util.ArrayList;
      
      public class Subsequences {
      
      public static void main(String[] args) {
      
          String s = "CCAATA CCGT";
          ArrayList<String> list = new ArrayList<String>(); // list of subsequence
      
          int n = 4; // subsequences of length
      
          String ss = s.replaceAll("\\s+", "");
          String substr = null;
      
          for (int i = 0; i <= ss.length() - n; i++) {
              substr = ss.substring(i, i + n);
              list.add(substr);
          }
      
          // --------Here the edits-------
          for (int i = 0; i < list.size(); i++) 
              System.println(i + " thru " + (i+n-1) + " : " + list.get(i))
          // -----------------------------
      
      }
      }
      

      【讨论】:

        【解决方案3】:

        您无需将n 添加到lastIndexOf,因为您将substring 分隔为4。List 中的每个条目由4 个字符组成。将您的索引检查更改为此

        (ss.lastIndexOf(list.get(i)) + n - 1)
        

        最后看起来像这样

         for (int i = 0; i < list.size(); i++) {
                System.out.println(ss.indexOf(list.get(i))
                        + " thru " + (ss.lastIndexOf(list.get(i)) + n - 1) + " : "
                        + list.get(i));
        
            }
        

        输出:

        0 thru 3 : CCAA   
        1 thru 4 : CAAT   
        2 thru 5 : AATA   
        3 thru 6 : ATAC   
        4 thru 7 : TACC   
        5 thru 8 : ACCG  
        6 thru 9 : CCGT   
        

        【讨论】:

          【解决方案4】:

          删除所有空格,循环:

          String data = "CCAATA CCGT";
          String replaced = data.replaceAll("\\s", "");
          for (int i = 0; i < replaced.length() - 4 + 1; i++) {
              System.out.println(replaced.subSequence(i, i + 4));
          }
          

          输出:

          CCAA
          CAAT
          AATA
          ATAC
          TACC
          ACCG
          CCGT
          

          【讨论】:

            【解决方案5】:

            我相信您的问题出在list.get(i + n - 1)。您当前正在迭代,使得每个子序列的 start 范围从 0list.size() - 1。最后一个有意义的子序列是位于list.size() - nlist.size() - 1 位置的n 字符。

            for (int i = 0; i < list.size() - n; i++) {
                System.out.println(ss.indexOf(list.get(i)) 
                    + " thru " + ss.lastIndexOf(list.get(i + n - 1)) + " : " 
                    + list.get(i));
            
                }
            

            【讨论】:

              猜你喜欢
              • 2015-03-24
              • 2020-03-30
              • 2015-01-11
              • 2020-07-21
              • 2012-10-10
              • 1970-01-01
              • 2012-11-16
              • 2014-01-20
              相关资源
              最近更新 更多