这是一个实现,我尚未对其进行测试,但您可以尝试了解一下。我会根据需要将 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();
}