2013-08-22 153 views
3

目標C中是否可以同時搜索多個不同字符串的NSString?例如,我想搜索字符串「good」,「great」,「awesome」,「incredible」,「fantastic」和「brilliant」中所有出現的字符串。在NSString中搜索多個字符串

我的第一個使用方法是使用NSString:rangeOfString:並循環多次(每個字符串一次),但它讓我感到如果使用更長的字符串集合,這可能變得效率低下且速度慢。

是否有像這樣搜索多個字符串的內置方式,還是應該創建我自己的方法?

編輯:結果在!

經過一段時間的基準測試後,我發現RegEx方法確實比循環rangeInString方法慢(慢兩倍多)。這些數字,你的愉快,如下:

隨着15萬字(〜1103,500個字符)和20比賽的話列表,目前

的NSString 5412場比賽: rangeInString搜索= 231.077ms
正則表達式搜索= 530.113ms

+0

第一眼我怕你將不得不爲「手動」迭代,但我希望有人會證明我錯了 –

+0

@GabrielePetronella我只是做了:) – 2013-08-22 16:05:17

+0

@ H2CO3,很好的答案,儘管正如你正確指出的那樣,正則表達式可能會更慢;) –

回答

4

這讓我感到,如果使用更長的字符串,這可能會變得效率低下,速度慢。

那麼,你有基準嗎?如果沒有,那麼你就沒有權利判斷它是「低效」和「慢」。過早優化是邪惡的。只要堅持那些漂亮和簡單的循環和- [NSString rangeOfString:]方法。


但是:真正回答你的問題,這不是不可能避免了手動循環。如果你使用NSRegularExpressiongood|great|awesome這樣的正則表達式,那麼你可以在一遍中找到所有的事件。 雖然使用正則表達式可能會比簡單的字符串搜索更慢。

+0

感謝您的建議。 我並不是故意**判斷它是低效率和慢速的,只是表明我最初想法的結構**可能是浪費的,因爲對於n個字符串的列表,它需要n遍做一些可以用更少的迭代完成的事情。 看起來像我會享受一個練習算法,通過自己的方法,並採取一些基準:) – sleeke

+1

@sleeke是的,實際上對代碼進行基準測試的價值超過了得分最高的SO用戶的猜測:)的想法是,CPU總是知道更快的速度,任何人都可以做。 – 2013-08-22 16:38:08

+0

同意,但對於個人項目,在SO上發佈問題並留待討論在工作日是一個更好的主意;)耗時的算法設計和基準測試是我業餘時間最好的一件事情:) – sleeke

0

是的,在內部,NSString是一個unichars數據blob。您可以檢索指向該指針的指針,然後讓多個隊列搜索其中的一部分,但您必須確保在空白字符之間進行分割,以便錯過兩個範圍的單詞部分。

+0

有內部不是「一個unichars的數據blob」的NSStrings。請求字符數據時,必須將其轉換爲UTF-16。無論如何,使用原始unicode代碼片段實現字符串搜索非常複雜。 –

1

正則表達式的使用非常廣泛,以至於執行效率很高。具體來說,正則表達式匹配將遍歷輸入字符串一次

NSRegularExpression *regex = 
    [NSRegularExpression regularExpressionWithPattern: @"(good|great|...)" 
              options: NSRegularExpressionCaseInsensitive 
               error: ...]; 
NSArray *matches = [regex matchesInString: string 
            options: 0 
            range: NSMakeRange(0, [string length])]; 

for (NSTextCheckingResult *match in matches) 
    ... 

下面是測試片段:

NSString *string = @"not good nor great"; 

    // as above 
    for (NSTextCheckingResult *match in matches) 
    NSLog (@"Match: %@", match); 

生產:

2013-08-22 10:21:11.644 foo[2454:707] Match: <NSSimpleRegularExpressionCheckingResult: 0x7fc954301650>{4, 4}{<NSRegularExpression: 0x7fc9543001c0> (good|great) 0x1} 
2013-08-22 10:21:11.644 foo[2454:707] Match: <NSSimpleRegularExpressionCheckingResult: 0x7fc954301540>{13, 5}{<NSRegularExpression: 0x7fc9543001c0> (good|great) 0x1}