ハッシュエントリー

唯一の最も一般的なバイナリのハッシュを議論します。

羅区P3370

質問の意味:異なる文字列をどのように多くの模索($ N \の当量10 ^ 4 $)がN文字列。

分析:

異なるハッシュ値が統計的にあり、次にどのように多くの、各文字列のハッシュ値を求めます。

シングルハッシュ

大きな素数、または自然のオーバーフローを選択します。

#include <ビット/ STDC ++ H>
 使用して 名前空間STDを、

typedefの長い 長いLL。
typedefの符号なしの長い 長いULL。
CONST ULLの基地 = 233 
ULL MOD = 212370440130137957ll。
const  int型 MAXN = 10000 + 10 int型のn; 
ULL F [MAXN]。
チャーS [MAXN]。

ULLハッシュ(CHAR S [])   // 自然溢出
{ 
    ULL ANS = 0 int型のlen =STRLEN(S);
    以下のためにint型 i = 0 ; iがLEN <; iは++ 
    { 
        ANS =(ベース * ANS +(ULL)S [i])と%MOD。
    } 
    戻りANS。
} 

設定 <ULL> ST。
INT メイン()
{ 
    scanf関数(" %のD "、&N)
    以下のためにint型 i = 0 ; iがn <; iは++ 
    { 
        scanf関数(" %sの" 、S); 
        st.insert(ハッシュ(S))。
    } 
    のprintf(" %d個の\ n " 、st.size())。
}

ダブルハッシュ

2つのモジュラ、ハッシュ衝突確率の使用がはるかに低くなるが、一定増加します。

#include <ビット/ STDC ++ H>
 使用して 名前空間STDを、

typedefの長い 長いLL。
typedefの符号なしの長い 長いULL。
CONST ULLの基地 = 233 
ULL MOD1 = 212370440130137957ll。
ULL MOD2 = 1 << 30 const  int型 MAXN = 10000 + 10 int型のn;
チャーS [MAXN]。

ULL HASH1(CHAR S [])   // 自然溢出
{ 
    ULL ANS =0 ;
    INT LEN = STRLEN(S)。
    以下のためにint型 i = 0 ; iがLEN <I ++の
    { 
        ANS =(ベース * ANS +(ウール)S [I])%MOD1と、
    } 
    戻りANS; 
} 
ウールHASH2(CHAR S [])   // 自然溢出
{ 
    ウールANS = 0 INT LEN = STRLEN(S)。
    以下のためにint型 i = 0 ; iがLEN <I ++の
    { 
        ANS =(ベースを* ANS +(ULL)S [i])と%MOD2。
    } 
    戻りANS。
} 

構造体ノード{ 
    ULLのX、Y。
} [MAXN] F。
BOOL CMP(ノード、ノードB)
{ 
    場合(AX == BX)   戻り AY < によって、
    リターン斧< BX。
} 

int型のmain()
{ 
    scanf関数(" %のD "、&N)
    以下のためにint型 i = 0 ; iがn <; iは++ 
    { 
        scanf関数(" %sの" 、S); 
        F [i]が.X= HASH1(S)。
        F [i]が.Y = HASH2(S)。
        // のprintf( "%LLD%LLD \ n"は、[I] .X、[I] .Y F、F)。
    } 
    ソート(F、F + N、CMP)。
    int型 CNT = 1 ;
    int型 iは= 0 ; iがN- < 1 ; iが++ 
    { 
        場合([I + F 1 .X] = [I] .X || F [I + F!1 ] .Y = [I] .Y fは! )CNT ++ ; 
    } 
    のprintf(" %d個の\ n " 、CNT)。
}

 

 

参考リンク:https://www.cnblogs.com/henry-1202/p/8868414.html

 

おすすめ

転載: www.cnblogs.com/lfri/p/11375253.html