std::string
誤解していたら申し訳ありませんが、通常のオブジェクトの代わりに、クエリ文字列の「部分文字列ビュー」を使用してマルチマップを検索できれば、問題は解決しますか?
その場合、以下の行に沿った何かが機能します (C++11 ベースのコーディングを使用):
部分文字列ビュー オブジェクト タイプを定義します。これは文字列と (from,to) オフセットから構成されますが、部分文字列のコピーは作成しません:
class substrview
{
std::string::const_iterator _from;
std::string::const_iterator _to;
public:
substrview(
const std::string &s,
const std::size_t from,
const std::size_t to)
: _from(s.begin()+from), _to(s.begin()+to)
{ }
std::string::const_iterator begin() const
{ return _from; }
std::string::const_iterator end() const
{ return _to; }
};
部分文字列ビューを使用してマルチマップを検索するには、次のstd::lower_bound
およびstd::upper_bound
メソッドを使用することをお勧めし<algorithm>
ます。
int main()
{
std::multimap<std::string,int> map {
{ "hello" , 1 },
{ "world" , 2 },
{ "foo" , 3 },
{ "foobar" , 4 },
{ "foo" , 5 },
};
std::string query { "barfoo" };
/* Search for all suffixes of "barfoo", one after the other: */
for (std::size_t i = 0 ; i < query.size() ; ++i) {
substrview subquery { query,i,query.size() };
auto found_from = std::lower_bound(begin(map),end(map),subquery,cmpL);
auto found_to = std::upper_bound(begin(map),end(map),subquery,cmpU);
/* Now [found_from,found_to) is the match range in the multi-map.
Printing the matches: */
while (found_from != found_to) {
std::cout << found_from->first << ", " << found_from->second << '\n';
++found_from;
}
}
}
cmpL
これを機能させるには、比較演算子and cmpU
(1 はlower_bound
、もう1 つは )を定義するだけでupper_bound
済みます。比較は非対称であるため、2 つ必要です: マルチマップ エントリを aと比較し、substringview
aをマルチマップ エントリと比較します。で):cmpL
substringview
cmpU
inline bool cmpL(
const std::pair<std::string,int> &entry,
const substrview &val)
{
return std::lexicographical_compare
(entry.first.begin(),entry.first.end(),val.begin(),val.end());
}
inline bool cmpU(
const substrview &val,
const std::pair<std::string,int> &entry)
{
return std::lexicographical_compare
(val.begin(),val.end(),entry.first.begin(),entry.first.end());
}
完全なコードの作業要点: https://gist.github.com/4070189