[英]Efficient way to replace chars in a string (java)?
我正在編寫一個小型 JAVA 程序,它:
我試圖做的聽起來像是“查找和替換”,但它不一樣,所以我認為清除它很重要。
無論如何,我想獲取此文本,查找第一個數組中的任何字符是否與文本中的字符匹配,如果匹配,則將其替換為第二個字符數組中的匹配字符(根據索引)。
我會用一個例子來解釋:假設我的文本(字符串)是:“java 太棒了!”; 我有 2 個數組 (char[]):“absm”和“!@*$”。
期望的結果是將 'a' 更改為 '!' , 'b' 到 '@' 等等.. 意味着結果文本將是:
“java太棒了!” 改為 -> "j@v@ i* @w*o$e!"
這樣做的最有效方法是什么,為什么? 我想過循環文本,但后來我發現它不是那么有效。
(可以使用StringBuilder /String 類)
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())
我猜您正在尋找StringUtils.replaceEach ,至少作為參考。
你需要它有多高效? 你這樣做是為了數百、數千、數百萬個單詞嗎???
我不知道它是否最有效,但是您可以在每個可能的標記上使用 string indexOf()
方法,它會告訴您它是否存在,然后您可以同時用相應的索引替換該索引來自另一個數組的字符。
Codewise,類似於(順便說一下,這是半偽代碼):
for(each of first array) {
int temp = YourString.indexOf(current array field);
if (temp >=0) {
replace with other array
}
}
將您擁有的 2 個數組放在 Map 中
Map<Character, Character> //or Map of Strings
其中鍵是“a”、“b”等……而值是您要替換的字符 - “@”等……
然后只需用值替換字符串中的鍵。
對於像這樣的小東西, indexOf() 搜索可能比地圖更快,同時“避免”接受答案的內部循環。 當然,循環仍然存在,在 String.indexOf() 內部,但它很可能被 JIT 編譯器優化為一個很好的方式,因為它被大量使用。
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 ,使其比人們猜測的更快。
此實用程序類替換 String 的一個字符或一組字符。 它相當於 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
由於知道是否應該替換字符的唯一方法是檢查它,因此您(或任何 util 方法)必須一個接一個地遍歷整個文本。 您永遠無法實現比O(n)更好的復雜性(n 是文本中的字符數)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.