Efficient way to replace chars in a string (java)?

て烟熏妆下的殇ゞ 提交于 2019-11-28 10:35:40
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;
            }

        }
    }

This way is efficient because it uses a StringBuilder to change the characters in place (if you used Strings you would have to create new ones each time because they are immutable.) Also it minimizes the amount of passes you have to do (1 pass through the text string and n passes through the first array where n = text.length())

I guess you are looking for StringUtils.replaceEach, at least as a reference.

How efficient do you need it to be? Are you doing this for hundreds, thousands, millions of words???

I don't know if it's the most efficent, but you could use the string indexOf() method on each of your possible tokens, it will tell you if it's there, and then you can replace that index at the same time with the corresponding char from the other array.

Codewise, something like (this is half pseudo code by the way):

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

Put the 2 arrays you have in a Map

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

where the key is "a", "b" etc... and the value is the character you want to substitute with - "@" etc....

Then simply replace the keys in your String with the values.

Ed Staub

For small stuff like this, an indexOf() search is likely to be faster than a map, while "avoiding" the inner loop of the accepted answer. Of course, the loop is still there, inside String.indexOf(), but it's likely to be optimized to a fare-thee-well by the JIT-compiler, because it's so heavily used.

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();
}

Update: The Oracle/Sun JIT uses SIMD on at least some processors for indexOf(), making it even faster than one would guess.

Since the only way to know if a character should be replaced is to check it, you (or any util method) have to loop through the whole text, character after the other. You can never achieve better complexity than O(n) (n be the number of characters in the text).

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!