2016-04-19 61 views
0

我有一個巨大的STL容器std::string(數十萬條目)。目前我正在使用vector,但我很樂意改變。內容按字母順序排序,由字母小寫字母a-z ñ組成。查找在有序STL容器中以前綴開頭的所有字符串(非低位ASCII)

我想實現一個函數,它接收一個const std::string& prefix並返回一對迭代器,一個指向以這樣的前綴開頭的第一個元素,另一個指向最後一個。如果沒有字符串匹配條件,則返回任意兩個相同的迭代器。我在查找時需要效率,因爲矢量很大,所以我想利用它爲二進制搜索進行排序。

我認爲std::lower_bound是我正在尋找,但我缺少一個函數來比較std::string s可以處理西班牙ñ

+0

你使用的是UTF-8嗎?只要你在你的搜索前綴字符串中使用與你在向量中使用的相同的編碼,你應該沒問題。爲了提高速度,您可以將前綴長度捕獲到lambda中,並調用'std :: string :: compare'的適當重載。 – paddy

+0

您可以編寫自定義比較函數以傳遞給'lower_bound()',但是您執行的任何比較都必須考慮字符集/區域設置,因爲「ñ」不是ASCII。 'std :: string'只知道'char'值,並沒有字符集/區域設置的概念,所以你需要手動處理它。在不同的字符集中''可以是不同的'char'值,在某些字符集中它根本不存在。 –

回答

1

您可以使用std::equal_range獲得與數值相同的整個範圍。如果集合中至少有一個匹配的字符串,它會給你一對迭代器,一個迭代器開始,一個迭代器超過範圍末尾。如果字符串不存在,它將會在字符串所屬的位置之後立即給出第一個點的兩個相同的迭代器。

鑑於你只關心尋找一個相同的子字符串,一個正常的字符串比較(的前N個字符)應該工作正常。如果你想支持(比如)一對輸入字符串,並找到它們之間的所有輸入,所以你需要從(比如說)「m *」到「o *」(用你的「ñ*」字符串視爲介於兩者之間),那麼你就必須要有一點點愛好者(通常的做法是建立一個以字符代碼作爲索引的對照表,並將相對順序作爲每個位置的值)。

+0

你可以用默認的'equal_range()'做前綴匹配,還是僅僅是一個全長比較?或者你需要一個自定義的比較仿函數來實現前綴匹配嗎? –

+0

@RemyLebeau:你可以傳遞一個比較對象,它可以做任何你指定的比較。在這種情況下,你會傳遞一個(例如)比較'return a.substr(0,N)

+0

我可能會使用其中一個'std :: string :: compare()'重載來避免不必要的分配,比如'return(a.compare(0,b.size(),b)== 0); ' –

相關問題