有效的方法来替换字符串中的字符(java)?

时间:2011-11-23 20:27:53

标签: java string replace char stringbuilder

我正在编写一个小型JAVA程序:

  • 将文本作为字符串
  • 采用2个字符阵列

我试图做的事情听起来像“找到并替换”但它不一样,所以我认为清除它很重要。

无论如何,我想获取此文本,查找第一个数组中的任何字符是否与文本中的字符匹配,如果是,请将其替换为第二个字符数组中匹配的字符(根据索引)。

我将用一个例子来解释: 让我说我的文字(String)是:“java真棒!”; 我有2个数组(char []):“absm”和“!@ * $”。

希望的结果是将'a'改为'!' ,'b'到'@'等等.. 意味着结果文本将是:

“java真棒!”改为 - > “j @ v @ i * @ w * o $ e!”

这样做最有效的方法是什么?为什么? 我考虑过循环文本,但后来发现它效率不高。

StringBuilder /可以使用String类)

7 个答案:

答案 0 :(得分:3)

我猜您正在寻找StringUtils.replaceEach,至少作为参考。

答案 1 :(得分:3)

StringBuilder sb = new StringBuilder(text);
    for(int i = 0; i<text.length(); i ++)
    {
        for (int j = 0; j < firstCharArray.length;j++)
        {
            if (sb.charAt(i) == firstCharArray[j])
            {
                sb.setCharAt(i, secondCharArray[j]);
                break;
            }

        }
    }

这种方式很有效,因为它使用StringBuilder来更改字符(如果你使用字符串,你每次都必须创建新的字符,因为它们是不可变的。)此外,它最大限度地减少了你必须做的传递量( 1遍历文本字符串,n遍历第一个数组,其中n = text.length())

答案 2 :(得分:1)

您需要它的效率如何?你这样做是为了数百,数千,数百万字吗???

我不知道它是否是最有效的,但你可以在每个可能的令牌上使用字符串indexOf()方法,它会告诉你它是否在那里,然后你可以在那里替换那个索引同时使用来自另一个数组的相应char。

Codewise,类似的东西(顺便说一下,这是半伪代码):

for(each of first array) {
    int temp = YourString.indexOf(current array field);
    if (temp >=0) {
        replace with other array
    }
}

答案 3 :(得分:1)

将您拥有的2个阵列放入地图

Map<Character, Character> //or Map of Strings

其中键是&#34; a&#34;,&#34; b&#34;等等...而值是你要替换的角色 - &#34; @&#34;等....

然后只需用值替换String中的键。

答案 4 :(得分:1)

对于像这样的小东西,indexOf()搜索可能比地图快,而“避免”接受答案的内部循环。当然,循环仍在那里,在String.indexOf()中,但是它可能会被JIT编译器优化为fare-the-well,因为它被大量使用。

static String replaceChars(String source, String from, String to)
{
    StringBuilder dest = new StringBuilder(source);
    for ( int i = 0; i < source.length(); i++ )
    {
        int foundAt = from.indexOf(source.charAt(i));
        if ( foundAt >= 0 )
            dest.setCharAt(i,to.charAt(foundAt));
    }
    return dest.toString();
}

更新:Oracle / Sun JIT在indexOf()的至少一些处理器上使用SIMD,使其比人们想象的更快。

答案 5 :(得分:0)

因为知道是否应该替换字符的唯一方法是检查它,你(或任何util方法)必须循环遍历整个文本,字符接着另一个。你永远无法实现比 O(n)更好的复杂性(n是文本中的字符数)。

答案 6 :(得分:0)

此实用程序类,用于替换一个字符或一个字符串的一组字符。它等效于bash tr和perl tr///,也就是音译。

/**
 * Utility class that replaces chars of a String, aka, transliterate.
 * 
 * It's equivalent to bash 'tr' and perl 'tr///'.
 *
 */
public class ReplaceChars {

    public static String replace(String string, String from, String to) {
        return new String(replace(string.toCharArray(), from.toCharArray(), to.toCharArray()));
    }

    public static char[] replace(char[] chars, char[] from, char[] to) {

        char[] output = chars.clone();
        for (int i = 0; i < output.length; i++) {
            for (int j = 0; j < from.length; j++) {
                if (output[i] == from[j]) {
                    output[i] = to[j];
                    break;
                }
            }
        }
        return output;
    }

    /**
     * For tests!
     */
    public static void main(String[] args) {

        // Example from: https://en.wikipedia.org/wiki/Caesar_cipher
        String string = "THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG";
        String from = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        String to = "XYZABCDEFGHIJKLMNOPQRSTUVW";

        System.out.println();
        System.out.println("Cesar cypher: " + string);
        System.out.println("Result:       " + ReplaceChars.replace(string, from, to));
    }
}

这是输出:

Cesar cypher: THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG
Result:       QEB NRFZH YOLTK CLU GRJMP LSBO QEB IXWV ALD