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;i while(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+1while(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