【问题标题】:Elegant solution to replace substrings替换子字符串的优雅解决方案
【发布时间】:2015-10-12 23:33:33
【问题描述】:

我遇到了一个具有挑战性的问题。我有一个未修改的字符串,例如abcdefg 和一个包含字符串和索引的对象数组。

例如,对象 1 包含 d 和索引 [1, 2];

然后我会将子字符串[1,2] 中的任何字母替换为d,得到的字符串看起来像adcdefg。

当替换文本的长度与替换文本的长度不同时,问题就出现了。我需要一些方法来跟踪长度变化,否则进一步替换的索引将不准确。

这是我目前所拥有的:

 for (CandidateResult cResult : candidateResultList) {
      int[] index = cResult.getIndex();

      finalResult = finalResult.substring(0, index[0]) + cResult.getCandidate()
              + finalResult.substring(index[1], finalResult.length()); //should switch to stringbuilder
 }
 return finalResult;

这不涉及上面提到的角落案例。

此外,如果有人想知道,这不是家庭作业。这实际上是针对我正在创建的 ocr 培训师计划的。

【问题讨论】:

  • 所以所有替换索引都引用原始字符串?是否有任何重叠区域,例如{'d': [1,2], 'h': [0,3]} ?
  • 是的,索引指的是原始字符串。不,没有重叠区域。

标签: java string substring


【解决方案1】:

这是一个实现,我尚未对其进行测试,但您可以尝试了解一下。我会根据需要将 cmets 添加到代码中。

/** This class represents a replacement of characters in the original String, s[i0:if], 
  *  with a new string, str. 
 **/
class Replacement{
    int s, e;
    String str;
    public Replacement(int s, int e, String str){ 
        this.s = s;
        this.e = e;
        this.str = str;
    }
}

String stringReplace(String str, List<Replacement> replacements){

    // Sort Replacements by starting index
    Collections.sort(replacements, new Comparator<Replacement>(){
        @Override public int compare(Replacement r1, Replacement r2){
            return Integer.compare(r1.s, r2.s);
        }
    };

    StringBuilder sb = new StringBuilder();
    int repPos = 0;

    for(int i = 0; i < str.length; i++){
        Replacement rep = replacements.get(repPos);
        if(rep.s == i){               // Replacement starts here, at i == s
            sb.append(rep.str);       // Append the replacement
            i = rep.e - 1;            // Advance i -> e - 1
            repPos++;                 // Advance repPos by 1
        } else {
            sb.append(str.charAt(i)); // No replacement, append char
        }
    }

    return sb.toString();
}

[编辑:] 看到 ptyx 的回答后,我认为这种方式可能更优雅。如果您以相反的顺序排序,则不必担心不同的长度:

String stringReplace(String str, List<Replacement> replacements){

    // Sort Replacements in reverse order by index 
    Collections.sort(replacements, new Comparator<Replacement>(){
        @Override public int compare(Replacement r1, Replacement r2){
            return -Integer.compare(r1.s, r2.s);  // Note reverse order
        }
    };

    // By replacing in reverse order, shouldn't affect next replacement.
    StringBuilder sb = new StringBuilder(str);
    for(Replacement rep : replacements){
        sb.replace(rep.s, rep.e, rep.str);
    }

    return sb.toString();
}

【讨论】:

    【解决方案2】:

    假设没有要替换的重叠范围,以相反的位置顺序处理您的替换 - 完成。

    你用什么替换 [5-6] 并不重要,它永远不会修改 [0-4] 因此你不需要为任何索引映射而烦恼,例如: [1,2]

    【讨论】:

      【解决方案3】:

      这似乎如你所愿,基本上你只是根据以前的插入翻译替换

      public static void main(String[] args) {
          Replacer[] replacers = {
                  new Replacer(new int[]{ 1 , 2 }, "ddd") ,
                  new Replacer(new int[]{ 2 , 3 }, "a")
          };
          System.out.println(
                  m("abcdefg", replacers));
      }
      
      public static String m(String s1, Replacer[] replacers){
          StringBuilder builder = new StringBuilder(s1);
          int translate = 0;
          for (int i = 0 ; i < replacers.length ; i++) {
              translate += replacers[i].replace(builder, translate);
          }
          return builder.toString();
      }
      
      public static class Replacer{
          int[] arr;
          String toRep;
      
          public Replacer(int[] arr, String toRep) {
              this.arr = arr;
              this.toRep = toRep;
          }
      
          public int replace(StringBuilder b, int translate){
              b.replace(arr[0] + translate, arr[1] + translate, toRep);
              return arr[1];
          }
      }
      

      【讨论】:

      • 我没有考虑到这一点,看来这只有在您的替换位置按升序排列时才有效
      猜你喜欢
      • 2023-03-19
      • 1970-01-01
      • 2011-10-15
      • 2011-02-13
      • 1970-01-01
      • 1970-01-01
      • 2018-04-28
      • 1970-01-01
      • 2011-05-05
      相关资源
      最近更新 更多