【问题标题】:Java deleteCharAt with ++ or -- [duplicate]Java deleteCharAt 带有 ++ 或 -- [重复]
【发布时间】:2018-04-12 15:36:21
【问题描述】:

我有以下代码:

public static void main(String[] args) {
    StringBuilder phoneNumber = new StringBuilder("828-707-5634");
    for(int i = 0; i < phoneNumber.length(); i++)
    {
      if (phoneNumber.charAt(i) == '-')
        phoneNumber.deleteCharAt(i--);
    }

    System.out.print(phoneNumber);
}

确实,这会从电话号码中删除破折号,但直觉上我希望它会删除破折号之前的字符(因为 --)。这如何/为什么起作用?此外,我发现如果我使用 ++ 或完全省略增量/减量,破折号仍然会被删除。

【问题讨论】:

  • 您在 for 循环中检查其内容期间正在更改对象......
  • i-- 将未更改的i 提供给该方法,然后递减该值。这与您拨打deleteCharAt(i); i--; 相同。 --i 操作符在提供方法之前会递减它。
  • 如果要删除破折号前的 de 字符,请使用 --i
  • 停止使用内联后缀和中缀操作。
  • 公平地说,这是减少索引的“正确”解决方案,因为您直接更新字符串。但我更喜欢简单地从头开始阅读,这样我就不必为新的长度而烦恼了。

标签: java


【解决方案1】:

deleteCharAt 接收到 unincrementedi,因为 expression i-- 的值是未递增值。这就是您的代码有效的原因,即使您依赖for 循环的增量表达式 来补偿i 中相当人为且毫无意义的减少。这一切对我来说似乎相当粗糙,如果第一个字符是破折号,将i 设置为 -1 会在调试期间引起注意。

最好在java.lang.String 中使用replace 方法。见replace String with another in java

其他我更喜欢

for (int i = 0; i < phoneNumber.length(); /*intentionally empty*/){
    if (phoneNumber.charAt(i) == '-'){
        phoneNumber.deleteCharAt(i);
    } else {
        ++i;
    }
}

虽然由于length()的反复评估,这仍然是O(N)问题的O(N2)解决方案!这可以通过向后运行循环来解决,这也将减少元素洗牌的次数:

for (int i = -1 + phoneNumber.length(); i >= 0; /*intentionally empty*/){
    if (phoneNumber.charAt(i) == '-'){
        phoneNumber.deleteCharAt(i);
    } else {
        --i;
    }
}

【讨论】:

  • "确实这会从电话号码中删除破折号,但直觉上我希望它会删除破折号之前的字符(因为 --) Lumbee"似乎您的第一个陈述完美地回答了 OP 问题。
  • 既然你已经添加了你喜欢的解决方案,对于这种代码我更喜欢for(int i = phoneNumber.length() -1; i &gt;= 0; --i) ...
  • @AxelH:是的,这减少了洗牌的次数。
  • 你应该总是在这里递减,否则可能会以OutOfBoundsException结尾,我们已经检查了将出现在那个位置的字符 PS:我喜欢长度前的-1,简单但更具可读性
猜你喜欢
  • 1970-01-01
  • 2011-09-21
  • 2016-06-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-24
  • 1970-01-01
  • 2012-12-01
相关资源
最近更新 更多