2013-05-06 90 views
1

假設有一個字符串:避免在一個字符串遞歸替換

"I'm a boy." 

和一些同義詞詞(以鍵值格式):

boy -> "male yong" 
yong -> "age under 18" 

如果我更換由同義詞詞串一個個,這將是:

步驟1,找到單詞「男孩」,並替換:"I'm a male young." 第2步,找字「young」並替換它:"I'm a male age under 18." 實際上我不需要遞歸替換,我只需要替換原始字符串,換句話說,第2步應該在原始字符串中找到「young」:「我是男孩。而不是「我是男性的年輕人」。有一個簡單的解決方案:

首先替換鍵%s和添加同義詞單詞的列表:

string: "I'm a %s" 
list: "male yong" 

然後格式字符串列表:

String.format(string, list) 

它工作正常,但愚蠢的,慢,任何人有更明確的解決方案?

+1

我不確定您的實際任務是什麼,但如果您需要排除之前任何轉換的結果,那麼請控制**搜索/替換的**起點**。 – 2013-05-06 02:02:31

+2

如果您可以清楚地識別哪些同義詞值包含其他同義詞,那麼您可以想象一個「圖」結構,其中不會評估爲其他同義詞的所有同義詞先被替換,然後是他們的「父母」等,直到您安全評估所有同義詞。不過,如果有圖表,那麼你的運氣不好。 – Patashu 2013-05-06 02:03:15

+0

同義詞可以是任意字符串,也可以是單個單詞(例如,鍵中沒有空格)?如果是後者,那麼你可以在空白處「拆分」字符串,並且對於拆分中的每個字符串嘗試同義詞,如果你找不到或者應用了一個,就繼續前進。這樣,任何單詞都不會被遞歸地同義詞。 – Patashu 2013-05-06 02:06:03

回答

1

僞代碼(未測試和功能名稱可能是錯誤的):

String[] arr = sentence.Split(" "); 
StringBuilder sb = new StringBuilder(); //can specify size for better results possibly 

for (String s :arr){ 
    if (dic.contains(s)){ 
     sb.append(dic.get(s)); 
    }else{ 
     sb.append(s); 
    } 
} 

sb.toString();//your replaced string 

我不知道是什麼的String.Format內部做,但它可能會做類似的事情,所以我懷疑你會得到一個性能提升。

+0

當然,你的意思是分割空白空間,而不是空字符串?否則,假設同義詞密鑰從來沒有空白,像這樣的是正確的答案。 – Patashu 2013-05-06 02:14:44

+0

@Patashu你是對的..謝謝 – 2013-05-06 02:15:08

+0

嗯 - 如果句子中有標點符號,比如片段「boy」。不會被字典當作「男孩」。所以我認爲你需要分裂......嗯......'\ b'? ('\ b'匹配單詞字符('[0-9a-zA-Z_]')和非單詞字符(其他任何字符)之間的邊界,所以它會分割帶連字符的單詞,但在其他所有單詞中都可以。) – Patashu 2013-05-06 02:20:01

0

該解決方案是與你相似,但它不使用的String.format

String s = "I'm a yong boy."; 
    Map<String, String> map = new HashMap<>(); 
    map.put("boy", "male yong"); 
    map.put("yong", "age under 18"); 
    // replace all keys with 1 char placeholders 
    int i = 0; 
    for (String key : map.keySet()) { 
     s = s.replace(key, "" + (char) i++); 
    } 
    // replace placeholders with values 
    int j = 0; 
    for (String v : map.values()) { 
     s = s.replace("" + (char) j++, v); 
    } 
    System.out.println(s); 

輸出

I'm a age under 18 male yong. 

如果我們使用StringBuilder的更換,但是這將是更長的時間碼速度可以提高。如果替換號碼小於31,則安全,此後它將開始替換空格