手書きのハッシュの代わりにunordered_map、unordered_set

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;
}

おすすめ

転載: blog.csdn.net/HangHug_L/article/details/114135343