unordered_mapにはヘッダーファイルが必要です#include <unordered_map>
unordered_setにはヘッダーファイルが必要です#include <unordered_set>
どちらもハッシュに基づいて実装されており、順序が正しくないため、追加、削除、変更、チェックの時間計算量はO(1)です。 map and setよりも高速で、バランスの取れたバイナリツリー(赤黒木)に基づいて実装され、順序付けられたシーケンスを動的に維持し、時間計算量はO(logn)です。
手動でハッシュテーブルを作成する方法については、以下を参照してください:ハッシュテーブルの予備学習、文字列ハッシュ
unordered_mapの紹介
unordered_map<key,value> m;
マップタイプを定義します。キーは主キーであり、値は値です。主キーから値へのマッピングを実現できます。これは、2次元配列のアップグレードです。2次元配列では、主キーのタイプはintのみです。添え字は0から始まり、マップはOKです。主キーは任意のタイプにすることができます。
基本的なフレームワークは次のとおりです。
#include <iostream>
#include <unordered_map>
using namespace std;
typedef pair<string,int> PSI;
int main(){
unordered_map<string,int> hash;
return 0;
}
一般的な操作
hash.size()
戻り値現在のマップコンテナサイズ(要素の数)は
hash.empty()
、容器が空のマップであるか否かを判断するが、空、空ではないリターン0戻す
hash.clear()
クリアし、すべてのマップ要素を
hash.erase(key)
して、削除キー要素
hash.erase(it)
要素を削除は、イテレータを指摘と組み合わせて一緒に使用することができます検索機能
1.要素
①を挿入しますhash["lyh"]=20;
挿入プロセス中に、最初にhash [key]を削除してから、再割り当てします。
と書くだけで、hash[key]
キーが存在する場合は取得プロセスのみがあり、キーが存在しない場合は挿入プロセスであり、デフォルトでは0が挿入されます。
②hash.insert(PSI("lyh",40));
同等:PSI t={"efg",456}; hash.insert(t);
ペアバイナリ構造の使用法を理解し、値を個別に割り当てることもできます、
t.first="efg";
t.second=456;
①と②の両方を挿入できますが、①は更新できます。マップには主キーが1つしかないため、繰り返すことはできません。キーがマップにすでに存在する場合は、メソッド①を使用して更新できますが、メソッド②は挿入されません。
2.アクセス要素
①主キーを介したシングルアクセス
cout<<hash["lyh"];
②イテレータを介して、すべてのトラバーサルまたはシングルアクセスを実現できます。
for (auto it=hash.begin();it!=hash.end();it++)
cout<<it->first<<" "<<it->second<<endl;
AutoはC ++で記述されており、変数のタイプを自動的に判別できます。実際には、
unordered_map<string,int>::iterator it;
hash[key]
現在のキーの値を返す検索操作であるメソッド①へのアクセスに注意してください。キーがハッシュに存在しない場合、デフォルトで挿入され、初期値は0になります。キーが存在するかどうかが不明な場合は、誤ってハッシュに挿入されないように、検索またはカウント機能を使用してキーが存在するかどうかを判断することをお勧めします。
3.判断 主キー存在する
hash.find(key);
指定されたキーが存在するかどうかを検索し、そこにあるイテレータのキーを指しているが、)それ以外の場合は(hash.endにイテレータポインティングを返します。
hash.count(key);
キーに対応する要素の数を返します。マップコンテナキーの繰り返しは許可されていないため、戻り値は0または1のみになります。これは、key-value要素が存在するかどうかを決定するためでもあります。
unordered_setの概要
unordered_set<int> hash;
上記のマップ
のマッピングはkey-> valueです。keyとvalueはどちらも任意のタイプにすることができますが、主キーを繰り返すことはできません。setは配列に似ており、int-> valueのマッピングのみになります。 、つまり、主キーは次のとおりです。ベクトルコンテナと同様にint型にすることができますが、セットの値を繰り返すことはできません。さらに、主キーintに基づくインデックス付けはサポートされておらず、イテレータを介してのみトラバースできます。つまり、setは値の値のみを格納できます。
基本的なフレームワークは次のとおりです。
#include <iostream>
#include <unordered_set>
using namespace std;
int main()
{
unordered_set<int> hash;
return 0;
}
一般的な操作
hash.size();
要素の数を取得する
hash.empty();
空かどうかを判断する
hash.clear();
セット
hash.erase(x);
をクリアする値x
hash.erase(it);
の要素を削除するイテレータが指す
hash.erase(first,last);
要素を削除するイテレータが指す[first、last)の間の要素を削除する
1.要素挿入関数の
hash.insert(x);
挿入要素xをコレクションに挿入します
2.アクセス要素
ベクトルは添え字アクセスをサポートし、マップは主キーアクセスをサポートします。ただし、セットにはイテレータに基づいて1つずつしかアクセスできません。
for (auto it=hash.begin();it!=hash.end();it++)
cout<<(*it)<<endl;
同様に、自動はunordered_set<int>::iterator it;
3.要素が存在するかどうかを判別します。
マップは値が存在するかどうかを判別できません。主キーが存在するかどうかを判別するためであり、主キーを繰り返すことはできません。セットでは、主キーが決定されるため、セットが決定します。値の値が存在するかどうか。
hash.find(x);
要素xを指すイテレータを返しますhash.end();
hash.count(x);
。存在しない場合は、それを指します。要素xがセットに存在するかどうかを判断し、戻り値は1または0です。
ハッシュテーブルで一般的に使用される操作は、挿入とフェッチ、数値の有無の判断、削除はほとんど使用されないことです。セットシミュレーションまたはマップシミュレーションを適切に選択できます。
マップとセットの違いは次のとおりです。
マップには値のペア<type1、type 2>(<key、value>)が格納され、セットには値が格納されます。
具体的には、find関数とcount関数には大きな違いがあります。マップは主キーを見つけることであり、セットは値を見つけることです。
タイトル説明
上の記述に基づい青単語のタイトル、代わりにunordered_mapとunordered_set使用する方法を紹介します。
タイトルの簡単な説明:
コレクションを維持し、次の操作をサポートします。
「Ix」、数字xを挿入、
「Q x」、数字xがセットに含まれているかどうかを尋ねます。
次に、N個の操作を実行し、各クエリ操作に対応する結果を出力する必要があります。
データ範囲
1≤N≤10 5
-10 9 ≤x≤10 9
分析:
どんなセットを取るべきですか?入力データxの範囲は2e9の範囲、データは-1e9から1e9ですが、実際には1e5か月しか入力されませんでした。これは、格納するための巨大な配列を開いたバレル行として、明らかに無駄であるため、アイデアの離散化です。 [-1e9,1e9]の入力データを[1,1e5]のデータにマッピングするため、ハッシュが使用されます。以前は手書きのハッシュでしたが、現在はstlコンテナを使用していますが、手書きのハッシュにはより大きな利点とより速いスピード。
unordered_setを使用してシミュレートします
セットは値の値のみを格納でき、値の値に従ってのみ検索できるため、各xを値の値として挿入する必要があります。幸い、質問では、xが表示された回数ではなく、xが表示されたかどうかが尋ねられます。セットコンテナ重複する要素を保存できません。
#include <iostream>
#include <unordered_set>
using namespace std;
int main()
{
unordered_set<int> hash;
int num,x;
char op[2];
cin>>num;
while (num--) {
cin>>op>>x;
if (op[0]=='I') hash.insert(x);
else hash.count(x)?puts("Yes"):puts("No");
}
return 0;
}
unordered_mapを使用してシミュレートする
unordered_map <key、value>、unordered_mapは、キーから値にマップされ、値ではなくキーによってのみ検出できるバイナリ構造<key、value>を挿入します。したがって、毎回入力されたxが主キーキーとして使用され、値は主キーキーの出現回数を維持します。質問は回数を必要としないため、次のような1記号を格納するだけで十分です。登場しました。
#include <iostream>
#include <unordered_map>
using namespace std;
int main()
{
unordered_map <int,int> hash;
int num,x;
char op[2];
cin>>num;
while (num--) {
cin>>op>>x;
if (op[0]=='I') hash[x]=1; //根据key在那里标记是否插入过
else hash.count(x)?puts("Yes"):puts("No");
} "hash.find(x)找到的是迭代器,找不到即指向hash.end()"
return 0;
}