【问题标题】:Java String replaceJava字符串替换
【发布时间】:2015-05-26 13:18:51
【问题描述】:

假设我有一个字符串"aabbccaa"。现在我想用另一个字符串替换给定字符串中出现的"aa"。但应该是以下方式。

"aa" 的第一次出现应替换为"1""aa" 的下一次出现应替换为"2",依此类推。

所以,字符串的结果变成了"1bbcc2"

【问题讨论】:

  • 如果我是你,我会从字符串创建一个 char 数组并手动完成。
  • 那个可以,但我想以某种方式为Java预定义String函数....
  • 我认为这不可能,可能必须是 char 数组和 for 循环。
  • 可以使用 Pattern 类来匹配 aa 并在匹配时保留一个计数器。但是,这将比简单地检查 indexOf 并将剩余的文本复制到 StringBuilder 中执行得更差。
  • 这看起来像是“切蛋糕的方法有多少?”。

标签: java string str-replace apache-stringutils


【解决方案1】:

您可以在计数器递增的 for 循环中使用 replaceFirst()...

for (int i = 1; string.contains("aa"); i++) {
    string = string.replaceFirst("aa", "" + i);
}

【讨论】:

  • 似乎最好使用StringBuilder 来防止每次发现模式时创建一个新的String
  • 这个问题是它的时间复杂度。这显然是一个O(n) 问题,但是这段代码每次都从头开始搜索字符串,即使您知道您已经处理过该部分字符串。设为O(n*r),其中 r 是要完成的替换次数。
  • @weston 是的,你是对的,但问题很简单,答案也很简单。如果他/她想让它更高效、更复杂,那是她/他的责任:)
  • 我只发表评论,因为作为得票最多的答案,更重要的是指出它的缺点。
【解决方案2】:

您可以使用MatcherappendReplacement 方法来做到这一点:

Pattern p = Pattern.compile("aa");
Matcher m = p.matcher("aabbccaahhhaahhhaaahahhahaaakty");
StringBuffer sb = new StringBuffer();
// Variable "i" serves as a counter. It gets incremented after each replacement.
int i = 0;
while (m.find()) {
    m.appendReplacement(sb, ""+(i++));
}
m.appendTail(sb);
System.out.println(sb.toString());

这种方法可以让您避免创建多个字符串对象 (demo)。

【讨论】:

    【解决方案3】:

    可以使用 Java 函数,但使用 char 数组并使用较低级别的逻辑会更快。

    String s = "aabbccaa";
    String target = "aa";
    int i = 1;
    String newS;
    
    for (int j = 0; j < s.length; j++) {
      newS = s.replaceFirst(target, i++);
      j += newS.length - s.length;
      s = newS;
    }
    

    【讨论】:

    • 奇怪的问题,我知道这显然是由于 for 循环而导致的 O(n) 时间复杂度,但是您在哪里找到了 java 内置函数的复杂性?因为我有时很好奇手动编写某些东西或使用 java 内置函数的方式是否更快。
    • replaceFirst 方法使用正则表达式来完成它的工作。虽然非常有用且花哨,但它们确实会导致运行时惩罚。对于简单的模式匹配,自己做可能会更快。
    【解决方案4】:

    这是一个解决方案:

        public static void main(String[] a) {
    
            int i = 1;
            String before = "aabbccaabbaabbaa";
            String regex = "aa";
    
            String after = substitute(i, before, regex);
    
            System.out.println(after);
    
        }
    
        private static String substitute(int i, String before, String regex) {
    
            String after = before.replaceFirst(regex, Integer.toString(i++));
    
            while (!before.equals(after)) {
    
                before = after;
                after = before.replaceFirst(regex, Integer.toString(i++));
    
            }
    
            return after;
    
        }
    

    输出: 1bbcc2bb3bb4

    【讨论】:

      猜你喜欢
      • 2021-01-27
      • 2015-05-02
      • 1970-01-01
      • 2015-12-23
      • 1970-01-01
      • 1970-01-01
      • 2015-05-01
      • 2013-07-09
      • 2016-07-19
      相关资源
      最近更新 更多