2011-03-29 43 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(); 
} 
相关问题