文字列を保存し、それぞれに一意の ID 番号を発行したいと考えています (インデックスで問題ありません)。各文字列のコピーが 1 つだけ必要であり、迅速な検索が必要です。パフォーマンスの低下に気付くほど頻繁に文字列がテーブルに存在するかどうかを確認します。これに使用するのに最適なコンテナは何ですか?文字列が存在する場合、どのように検索しますか?
8 に答える
tr1::unordered_map をお勧めします。これはハッシュマップとして実装されるため、ルックアップの予想される複雑さは O(1) で、最悪の場合は O(n) になります。コンパイラが tr1 をサポートしていない場合は、boost の実装もあります。
#include <string>
#include <iostream>
#include <tr1/unordered_map>
using namespace std;
int main()
{
tr1::unordered_map<string, int> table;
table["One"] = 1;
table["Two"] = 2;
cout << "find(\"One\") == " << boolalpha << (table.find("One") != table.end()) << endl;
cout << "find(\"Three\") == " << boolalpha << (table.find("Three") != table.end()) << endl;
return 0;
}
これを試して:
(出典: adrinael.net )
std::map を試してください。
何よりもまず、選択肢を定量化できなければなりません。また、あなたが興味を持っている主な使用パターンは、挿入ではなくlookupであると教えてくれました。
N
をテーブルにあると予想される文字列の数にしC
、上記のテーブル (またはテーブルに対してチェックされる文字列) に存在する任意の文字列の平均文字数を とします。
ハッシュベースのアプローチの場合、ルックアップごとに次の費用がかかります。
O(C)
- 検索しようとしている文字列のハッシュを計算するO(1 x C)
との間。はハッシュ キーに基づいてバケットをトラバースすることで予想されるコストです。ここでは を掛けてO(N x C)
、ルックアップ キーに対して各文字列の文字を再チェックします。1..N
C
- 合計時間: ~の
O(2 x C)
間O((N + 1) x C)
に
std::map
基づくアプローチ(赤黒木を使用) の場合、ルックアップごとに次のコストを支払います。- 合計時間: ~の間
O(1 x C)
-O(log(N) x C)
ここO(log(N))
で、 は最大ツリー トラバーサル コストであり、O(C)
はツリー トラバーサル中にルックアップ キーを再チェックするためにstd::map
一般的な実装にかかる時間です。less<>
- 合計時間: ~の間
の値が大きくN
、log(N) 未満の衝突を保証するハッシュ関数がない場合、または単に安全にプレイしたい場合は、ツリーベースの ( std::map
) アプローチを使用することをお勧めします。N が小さい場合は、必ずハッシュベースのアプローチを使用してください (ハッシュの衝突が少ないことを確認しながら)。
ただし、決定を下す前に、次のことも確認する必要があります。
インデックスが配列へのインデックスである場合、配列は問題なく機能するように聞こえます。存在するかどうかを確認するには、インデックスが配列の境界内にあり、そのエントリが NULL でないことを確認してください。
編集:リストを並べ替える場合は、高速検索が必要なバイナリ検索を常に使用できます。
編集: また、文字列を検索する場合は、いつでも astd::map<std::string, int>
も使用できます。これにより、適切な検索速度が得られるはずです。
検索する文字列は静的に利用できますか? 完全なハッシュ関数を見たいと思うかもしれません
std::map を使用するのが最も簡単です。
それはこのように動作します:
#include <map>
using namespace std;
...
map<string, int> myContainer;
myContainer["foo"] = 5; // map string "foo" to id 5
// Now check if "foo" has been added to the container:
if (myContainer.find("foo") != myContainer.end())
{
// Yes!
cout << "The ID of foo is " << myContainer["foo"];
}
// Let's get "foo" out of it
myContainer.erase("foo")
おそらくGoogleのスパースハッシュ