字符串中字符替换的高效算法

时间:2016-02-05 11:23:03

标签: java algorithm

我有两个字符串

  1. 111TTT0000TT11T00
  2. 001101
  3. 现在我想用字符串2中的字符替换字符串1中T的所有外观。例如,第一个T为0,第二个T为0,第三个T为1,依此类推。

    这样做的一种方法是使用while循环并比较每个角色,但在编程意义上,这不是一种很好的方法。任何人都可以使用JAVA更好的算法解决它吗?

    public void DataParse(String point, String code)
    {
    
        //////////tln("Point:"+point);
        //////////tln("code:"+code);
        //  //////////tln(baseString_temp);
    
        int counter=0;
    
        while(baseString_temp.contains(point))
        {      
            if(code!=null)
            {
                String input=String.valueOf(code.charAt(counter));
                //zzzzz(input);
    
    
                baseString_temp=baseString_temp.replaceFirst(point,input);
                counter=counter+1;
            }
        }
    
        ////////////System.out(baseString_temp);
    }
    

2 个答案:

答案 0 :(得分:5)

每次使用containsreplaceFirst时,都会强制程序枚举字符串开头的字符。我相信单程通过会更好:

public static String replaceToken(String primary, String secondary, char token) {

   char [] charArray =primary.toCharArray();

   int counter = 0;
   for(int i=0; i<charArray.length; i++){
       if(charArray[i]==token){
           charArray[i] = secondary.charAt(counter);
           counter++;
           if(counter>=secondary.length()) break;
       }
   }
   return new String(charArray);
}    


public static void main(String[] args) {       
   String result = replaceToken("111TTT0000TT11T00", "001101", 'T');
}

如果你真的想使用RegExp 那么多,那么你就是:

public static String replaceSequence(String primary, String secondary, String sequence){

    Pattern pattern = Pattern.compile(sequence + "+");
    Matcher matcher = pattern.matcher(primary);

    int counter = 0;
    char [] charArray = primary.toCharArray();

    while(matcher.find() && counter<secondary.length()){
        for(int i = matcher.start(); i<matcher.end(); i++){
            charArray[i] = secondary.charAt(counter++);
            if(counter>=secondary.length()) break;
        }
    }
    return new String(charArray);
}

但是,根据您的任务描述,我更喜欢第一种方法。

答案 1 :(得分:1)

有几件事。因为字符串是不可变的,

baseString_temp=baseString_temp.replaceFirst(point,input);

将始终创建一个新的String对象(此外,它从头开始查找字符串,查找point)。如果你使用StringBuilder,你只需要分配一次内存,然后就可以改变它。实际上,使用Ken的答案中的数组会更好,因为它分配的次数更少,方法调用的开销也更少。

另外,我想象contains()使用自己的循环,在最坏的情况下会转到字符串的末尾。您只需要遍历字符串一次,并在进行时替换。

工作示例:

public class Test {

  private static String replace(char what, String input, String repls) {
    StringBuilder sb = new StringBuilder(input);
    int replIdx = 0;
    for (int i = 0; i < input.length(); i++) {
      if (input.charAt(i) == what) {
        sb.setCharAt(i, repls.charAt(replIdx++));
      }
    }
    return sb.toString();
  }

  public static void main(String[] args) {
    System.out.println(replace('T', "111TTT0000TT11T00", "001101"));
  }
}