Java:创建没有匹配连续字符的字符串时索引超出范围的异常

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java:创建没有匹配连续字符的字符串时索引超出范围的异常相关的知识,希望对你有一定的参考价值。

这是我的函数,它以字符串作为输入,例如aabbaaa。如果下一个字符相同,我将删除该字符。通过这种方式,我将删除连续出现的字符,即字符串将变为aba。但它扔给我indexoutofbounds exception

static int alternatingCharacters(String s)

    StringBuilder sb = new StringBuilder(s);
    try
    
        for(int i = 0; i < sb.length(); i++)
        
            while (sb.charAt(i) == sb.charAt(i+1) && i+1<sb.length())
            
                sb=sb.deleteCharAt(i);
            
        
    
    catch(Exception e)
    
        e.printStackTrace();
    

    return 0;
    System.out.println(sb);

答案

无论例外,这是从字符串中删除字符的效率非常低的方法。

每当你调用sb.deleteCharAt(i)时,它必须将所有字符移动到i的右边,然后是1.在最坏的情况下,这具有二次时间复杂度。

相反,简单地移动角色,然后修剪结束效率要高得多:

StringBuilder sb = new StringBuilder(s);
if (!s.isEmpty()) 
  int len = 1;
  for (int i = 1; i < sb.length(); ++i) 
    if (sb.charAt(i) != sb.charAt(len - 1)) 
      sb.setCharAt(len++, sb.charAt(i));
    
  
  sb.setLength(len);

这具有线性时间复杂度。

您可以通过直接在char[]上直接操作来直接执行此操作:

if (!s.isEmpty()) 
  char[] cs = s.toCharArray();
  int len = 1; // Start at 1, since the first character isn't equal to the one before it.
  for (int i = 1; i < cs.length; ++i) 
    if (cs[i] != cs[len-1]) 
      cs[len++] = cs[i];
    
  
  s = new String(cs, len);

另一答案
while (sb.charAt(i) == sb.charAt(i+1) && i+1<sb.length())

在这一行中,sb.charAt(i) == sb.charAt(i+1)i+1<sb.length()之前被评估,这意味着只有在您尝试检索后才检查后续字符是否存在。交换这两个条件,以便之前执行检查。

另一答案

由于i+1,该指数超出界限

由于for(int i = 0; i < sb.length(); i++)符号,length - 1使我从0变为less than

这是正确的,因为String或N字符将从索引0开始并在索引N-1处完成。

当你在i+1循环中执行for时,当它到达索引i的最后一个字符时,i+1会退出字符数组边界。

另一答案

你在评论中提到的问题是while循环 - 所以你应该首先检查i + 1 < sb.length(),然后检查sb.charAt(i) == sb.charAt(i + 1)

另外 - 另外两件事:

  • 删除println语句,因为这使它不能编译
  • 没有点返回int(并硬编码为0),所以将其更改为String

例:

static String alternatingCharacters(String s) 
    StringBuilder sb = new StringBuilder(s);
    try 
        for (int i = 0; i < sb.length(); i++) 
            while (i + 1 < sb.length() && sb.charAt(i) == sb.charAt(i + 1)) 
                sb = sb.deleteCharAt(i);
            
        
     catch (Exception e) 
        e.printStackTrace();
    

    return sb.toString();

Online Demo

另一答案

你的问题是你正在迭代到sb.length(),然后在你正在使用的while条件的循环内:

while (sb.charAt(i) == sb.charAt(i+1) && i+1<sb.length())

而qazxsw poi这句话是导致qazxsw poi的原因,因为在sb.charAt(i+1)中没有这样的指数。

当循环到达最后一个元素时,你在IndexOutOfBoundException之前的while中调用string,这样它就会一直执行。

你需要做的是交换sb.charAt(i+1)循环中的两个条件:i+1<sb.length()

另一答案

当您引用不存在的索引时,通常会导致索引超出范围。还记得索引计数从0开始而不是1.在最后一个循环中,while将是while(i+1<sb.length() && sb.charAt(i) == sb.charAt(i+1)),由于你的上边界是sb.charAt(i+1),它不存在,修复这个只是让你的上边界7 + 1 = 8

另一答案

循环和删除肯定会导致sb.Length()

for(int i = 0; i < sb.length() - 1; i++)

并且你仍然迭代直到达到5,这将导致异常

您可以使用Regex构建一个干净的解决方案:

IndexOutOfBoundsException

以上是关于Java:创建没有匹配连续字符的字符串时索引超出范围的异常的主要内容,如果未能解决你的问题,请参考以下文章

Java charAt() 字符串索引超出范围:5

/ password-reset /时的IndexError:重置密码时字符串索引超出范围

线程“主”java.lang.StringIndexOutOfBoundsException 中的异常:字符串索引超出范围:7

python 列表,元组,字符串 切片 超出索引值不报错

Hibernate OGM - java.lang.StringIndexOutOfBoundsException:字符串索引超出范围:-1

数组索引超出范围