2012-03-23 32 views
3

我想要替換字符串中的一個字符(位),這是一個二進制數。對於位替換,我設計了一種方法,它使用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是非常大的。有沒有其他方法,以便比上述方法更少的時間內完成任何位的替換?

回答

3

如果您使用的StringBuffer代替String,你可以這樣做:

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

如果比特串只會由一個線程訪問,使用StringBuilder而不是StringBuffer會更快,因爲它避免了不需要的同步。 – matts 2012-03-23 15:17:47

+0

好的提示。 OP表示認爲。 – 2012-03-23 15:21:42

0

你可以做到這一點,但我不知道這是否是任何更快

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

的性能問題,你正在看到是因爲Java字符串是不可變的。換句話說,一旦創建了字符串,就不能更改字符串。因此,要更改字符串中的一個字符,JVM必須複製整個字符串,如果字符串很大,則需要一段時間。

在上面的代碼中,實際上甚至比您將字符串的第一部分和字符串的第二部分複製到一個字符之外,然後必須將這些副本複製到最後結果。如果上述代碼由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); 
+0

很酷,我以前不知道BitSet。但是,一個可能的問題是,如果OP需要重複地將其轉換爲字符串表示並將其轉換爲字符串表示,那麼這是一種痛苦。 – matts 2012-03-23 15:14:44

+0

我同意。就像我在答案中所說的那樣,'BitSet'在這裏將如何完成取決於數據的處理方式。如果它需要再次輸出爲'String',則立即轉換爲'BitSet'可能會帶來太多的開銷,但如果代碼只需要檢查和修改數據,那麼'BitSet'可能是理想的。 – 2012-03-23 15:18:31

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)); 
} 
相關問題