Java:创建没有匹配的连续字符的字符串时索引越界异常

Java:创建没有匹配的连续字符的字符串时索引越界异常,java,string,Java,String,这是我的函数,它以字符串作为输入,例如aabbaaa。如果下一个字符相同,我将删除该字符。通过这种方式,我删除了连续出现的字符,即字符串将变成aba。但它正在抛出我的索引自动边界异常 static int alternatingCharacters(String s) { StringBuilder sb = new StringBuilder(s); try { for(int i = 0; i < sb.length(); i++)

这是我的函数,它以字符串作为输入,例如
aabbaaa
。如果下一个字符相同,我将删除该字符。通过这种方式,我删除了连续出现的字符,即字符串将变成
aba
。但它正在抛出我的索引自动边界异常

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);
}
静态int交替字符(字符串s)
{
StringBuilder sb=新的StringBuilder;
尝试
{
for(int i=0;iwhile(sb.charAt(i)=sb.charAt(i+1)和&i+1您的问题是,您正在迭代,直到
sb.length()
,然后在使用的
条件下,在
的循环中:

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

while(sb.charAt(i)=sb.charAt(i+1)和&i+1
while(sb.charAt(i)=sb.charAt(i+1)和&i+1索引越界通常是在引用不存在的索引时引起的。还要记住,索引计数从0开始,而不是从1开始。在最后一个循环中
sb.charAt(i+1)
将是
7+1=8
,这是不存在的,因为您的上限是
sb.Length()
,要解决此问题,只需将您的上限
设置为(int i=0;i
索引因
i+1

(int i=0;i
使i从0变为
长度-1
,因为
小于
符号

这是正确的,因为字符串或
N
字符将从索引0开始,在索引
N-1
结束


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

如注释中所述,您的问题是
while
循环-因此您应该首先检查
i+1
然后选中
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();
}
静态字符串替换字符(字符串s){
StringBuilder sb=新的StringBuilder;
试一试{
for(int i=0;i

不管异常情况如何,这是一种从字符串中删除字符的非常低效的方法

每次调用
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);
}

循环和删除肯定会导致
IndexOutOfBoundsException

StringBuilder sb = new StringBuilder("hello"); // length is 5
sb.deleteCharAt(2);                            // length is 4
你仍然迭代直到达到5,这将导致异常

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

"aaabbcccc".replaceAll("([a-z])\\1{1,}", "$1"); // the result will be abc

sb.charAt(i+1)和&i+1我怀疑这是在
返回后用
println
编译的。@Worthless意味着把
的两边都转过来,这样
charAt(i+1)
是安全的。
返回s.replaceAll(()\\1+,“$1”)
谢谢,伙计,它工作得很好。虽然这不会是一个错误。我在考虑其他复杂的事情,但不是这个简单的错误。如果你在
循环时不交换
中的检查顺序,这仍然会引发异常。
StringBuilder sb = new StringBuilder("hello"); // length is 5
sb.deleteCharAt(2);                            // length is 4
"aaabbcccc".replaceAll("([a-z])\\1{1,}", "$1"); // the result will be abc