字符替换在字符串中占用很长时间

时间:2012-03-23 14:59:02

标签: java binary

我正在尝试替换字符串中的单个字符(位),这是一个二进制数。对于位替换,我设计了一个方法,它使用符合给定索引的string.substring()方法简单地对字符串进行分区,然后连接所有。以下是方法 -

    /*
     *Method will replace the index-th bit with bitToInsert in the given str
     */
    String str = "11000110100110011111"; 
    int index = 5;
    int bitToInsert = 0;
    if (index == 0) {
        str = str.substring(0, str.length() - 1) + bitToInsert;
    } else {
        str = str.substring(0, str.length() - index - 1) + bitToInsert + str.substring(str.length() - index);
    }

这很好用,但是当给定str非常大时,这需要花费很多时间来替换一点。还有其他方法,所以与上述方法相比,任何位的替换都可以在更短的时间内完成吗?

4 个答案:

答案 0 :(得分:4)

您遇到的性能问题是因为Java字符串不可变。换句话说,一旦创建了String,就无法更改它。因此,要更改String中的一个字符,JVM必须复制整个String,如果它是一个大字符串,则需要一段时间。

在上面的代码中,实际上甚至比这更糟糕了,因为你正在复制字符串的第一部分和字符串的第二部分而不是一个字符,然后必须将这些副本复制到最终结果中。如果上面的代码由using a StringBuilder构建目标字符串,则可以提高性能,因此您只需要复制一次。

如果你真的在处理长二进制数,你应该考虑using a BitSet。这对你有用的程度取决于你翻转一些数据后你对数据做了什么。

 String str = "11000110100110011111"; 
 BitSet bitSet = new BitSet(str.length());

 //All bits are unset at first so set any that correspond to a '1' in the String
 for (int i = 0; i < str.length(); i++) {
   if (str.charAt(i) == '1') {
     bitSet.set(i);
   }
 }

 int index = 5;
 boolean bitToInsert = false; //i.e. 0
 bitSet.set(index, bitToInsert);

答案 1 :(得分:3)

如果您使用StringBuffer代替String,则可以执行此操作:

StringBuffer sb = new StringBuffer("11000110100110011111");
sb.setCharAt(index, '0');

答案 2 :(得分:1)

使用BitSet和StringBuffer是个好主意。但是,我还有另一个建议针对低内存和高速进行了优化 根据二进制数的长度,使用int或long。 如果它不能长期使用,可以更好地满足您的需求。

我将在这里演示如何使用字节类型数组存储11000110100110011111:

 byte [] bits = new byte[1000];
 String str = "11000110100110011111";

 int arrayIndex=0; //position in array
 int bitIndex=0; //which bit at bits[arrayIndex] is it

 //put your bits into a byte array
 for (int i=0; i<str.length(); i++){
     arrayIndex = i / 8;
     bitIndex = i % 8; //you can have max 8 bits in a byte

     bits[arrayIndex]=  (byte) (bits[arrayIndex] | ((Byte.parseByte(""+str.charAt(i)) << bitIndex)));
 }

这是您更改特定位的方式:

 //for replacing bit bitNumber with bitValue (where bitValue is 0 or 1)
 void changeBit(int bitNumber, byte bitValue){
     int arrayIndex= bitNumber / 8;
     int bitIndex= bitNumber % 8;

     //clear bit first
     byte crtBit = (byte)(1 << bitIndex);
     crtBit = (byte) ~crtBit;
     bits[arrayIndex]= (byte) (bits[arrayIndex] & crtBit);
     //set bit to new value
     bits[arrayIndex]= (byte) (bits[arrayIndex] | (bitValue << bitIndex));
 }

答案 3 :(得分:0)

你可以这样做,但我不知道它会不会更快

String temp = "1111111111111";
char[] array = temp.toCharArray();
array[5] = '0';
temp = new String(array);