2011-03-29 42 views
25

Java中的字符串處理是我努力要學會做的很好的事情。目前我想接收一個字符串並替換我找到的任何字符。什麼是替換字符串中多個字符的有效方法?

這是我目前效率低下(和有點傻海事組織)的職能。它被寫入只是工作。

public String convertWord(String word) 
{ 
    return word.toLowerCase().replace('á', 'a') 
          .replace('é', 'e') 
          .replace('í', 'i') 
          .replace('ú', 'u') 
          .replace('ý', 'y') 
          .replace('ð', 'd') 
          .replace('ó', 'o') 
          .replace('ö', 'o') 
          .replaceAll("[-]", "") 
          .replaceAll("[.]", "") 
          .replaceAll("[/]", "") 
          .replaceAll("[æ]", "ae") 
          .replaceAll("[þ]", "th"); 
} 

我跑1,000,000的運行,並花了8182ms。那麼我應該如何改變這個功能來提高效率呢?

發現

解決方案:

功能轉換到這個

public String convertWord(String word) 
{ 
    StringBuilder sb = new StringBuilder(); 

    char[] charArr = word.toLowerCase().toCharArray(); 

    for(int i = 0; i < charArr.length; i++) 
    { 
     // Single character case 
     if(charArr[i] == 'á') 
     { 
      sb.append('a'); 
     } 
     // Char to two characters 
     else if(charArr[i] == 'þ') 
     { 
      sb.append("th"); 
     } 
     // Remove 
     else if(charArr[i] == '-') 
     { 
     } 
     // Base case 
     else 
     { 
      sb.append(word.charAt(i)); 
     } 
    } 

    return sb.toString(); 
} 

運行此功能1,000,000次需要518ms。所以我認爲這是有效的。感謝您的幫助球員:)

+3

*部分*工作在這裏:http://stackoverflow.com/questions/1008802/converting-symbols-accent-letters-to-english-alphabet。我不知道'æ'和'þ'。 – Kobi 2011-03-29 09:52:36

回答

19

您可以創建一個長度爲Character.MAX_VALUE的String []表。 (包括映射到小寫)

由於替換變得更加複雜,執行它們的時間將保持不變。

private static final String[] REPLACEMENT = new String[Character.MAX_VALUE+1]; 
static { 
    for(int i=Character.MIN_VALUE;i<=Character.MAX_VALUE;i++) 
     REPLACEMENT[i] = Character.toString(Character.toLowerCase((char) i)); 
    // substitute 
    REPLACEMENT['á'] = "a"; 
    // remove 
    REPLACEMENT['-'] = ""; 
    // expand 
    REPLACEMENT['æ'] = "ae"; 
} 

public String convertWord(String word) { 
    StringBuilder sb = new StringBuilder(word.length()); 
    for(int i=0;i<word.length();i++) 
     sb.append(REPLACEMENT[word.charAt(i)]); 
    return sb.toString(); 
} 
+0

這是幫助我創建當前代碼的解決方案。所以我接受了這個。但是,邁克拉也幫了很多忙。 – 2011-03-29 10:37:40

+1

起初看起來有點瘋狂,但事實證明,這個數組只有64KB,並不是那麼糟糕。 – Kobi 2011-03-29 10:45:58

+0

@Kobi,這種查找速度非常快,不需要任何對象。 convertWord()只創建一個臨時對象(StringBuilder) – 2011-03-29 10:54:19

8

我的建議是:

  • 的字符串轉換爲char []數組運行通過陣列
  • ,一個接一個(例如,測試每個字符用開關語句),如果需要
  • 轉換的字符[]數組返回一個字符串

我覺得這可能是你會在純Java獲得最快的性能替換它。

編輯:我注意到你正在做一些改變,改變字符串的長度。在這種情況下,同樣的原則適用,但是您需要保留兩個數組並分別增加源索引和目標索引。你可能還需要調整目標陣列的大小,如果你用完了目標空間(即重新分配一個更大的陣列並將陣列拷貝到現有的目標陣列中)

+1

這可能工作。 – 2011-03-29 09:51:35

+1

基本上,你應該遍歷字符並使用'StringBuilder'。 – Kobi 2011-03-29 09:54:23

+1

我會做同樣的事情,如果你不介意使用更多的空間,只需要一個小的變體:我會使用一個'Map ',其中鍵是你想要替換的字符集,這些值是相應的替代品。這避免了'switch'語句。 – MarcoS 2011-03-29 09:54:35

0

我懷疑,你可以加速'字符替換'真。至於正則表達式替換的情況,您可以事先編譯正則表達式

0

使用函數String.replaceAll。 你想要的東西類似的好文章:link

0

任何時候,我們有這樣的問題,我們使用正則表達式是它們是目前對付你正在嘗試做的最快方法。

您是否已經嘗試過正則表達式?

0

我認爲效率低下的是你要再次檢查已被替換的字符,這是無用的。

我會得到String實例的charArray,遍歷它,併爲每個角色的垃圾郵件一系列的if-else這樣的:

char[] array = word.toCharArray(); 
for(int i=0; i<array.length; ++i){ 
    char currentChar = array[i]; 
    if(currentChar.equals('é')) 
     array[i] = 'e'; 
    else if(currentChar.equals('ö')) 
     array[i] = 'o'; 
    else if(//... 
} 
2

我的第一選擇是使用一個StringBuilder,因爲你需要從字符串中刪除一些字符。

第二種選擇是迭代拋出字符數組,並將處理後的字符添加到字符串原始大小的另一個數組中。然後您需要複製數組以修剪可能未使用的位置。

之後,我會做一些性能測試,看看女巫更好。

5

我的實現基於查找表。

public static String convertWord(String str) { 
    char[] words = str.toCharArray(); 
    char[] find = {'á','é','ú','ý','ð','ó','ö','æ','þ','-','.', 
      '/'}; 
    String[] replace = {"a","e","u","y","d","o","o","ae","th"}; 
    StringBuilder out = new StringBuilder(str.length()); 
    for (int i = 0; i < words.length; i++) { 
     boolean matchFailed = true; 
     for(int w = 0; w < find.length; w++) { 
      if(words[i] == find[w]) { 
       if(w < replace.length) { 
        out.append(replace[w]); 
       } 
       matchFailed = false; 
       break; 
      } 
     } 
     if(matchFailed) out.append(words[i]); 
    } 
    return out.toString(); 
} 
相關問題