4

既知のサイズnのキーの配列またはリストがあります。このリストに一意のキーがいくつあるかは不明です。0からnまでの可能性があります。キーは特定の順序ではなく、実際にはそうすることはできません。これらのキーには、等しいまたは不等式のみの、より大きいまたはより小さいという概念がないためです。ハッシュマップと言う前に、そのアイデアにレンチを投げると思うもう1つの条件があります。各キーの値はプライベートです。キーについて取得できる唯一の情報は、それが別のキーと等しいかどうかです。だから基本的に:

class key{
    private:
        T data;
        ...
    public:
        ...
        bool operator==(const key &k){return data==k.data}
        bool operator!=(const key &k){return data!=k.data}
};

key array[n];

さて、配列内のキーの半分以上が線形時間で同じキーであるかどうかを判断できるアルゴリズムはありますか?そうでない場合は、O(n * log(n))はどうですか?たとえば、配列に3つの一意のキーしかないとします。配列の60%には、key.data == foo、30%key.data == bar、および10%key.data==derpのキーが入力されています。アルゴリズムは、50%を超えるキーが同じ種類(data == fooのキー)であると判断し、それらのキーの1つを返すだけで済みます。

私の教授によると、それはO(n)時間で実行できますが、O(n * log(n))時間で実行できるものを見つけるだけでよいと彼は言います。

4

3 に答える 3

5

さらに比較するために任意のキーを抽出して保持できる場合は、Boyer-Moore多数決アルゴリズムが最適です。

于 2013-02-13T05:49:32.367 に答える
0

BMアルゴリズムを使用したくない場合は、同じアイデアに基づいて次の2つのアルゴリズムを使用できます。

アルゴリズムa。各実行で、各要素の配列を調べながら、MのセットS(Nのごく一部、たとえば10)のペア要素数を維持します。

1.1. If element E is in the set, increase count of the corresponding pair (E,count) -> (E, count+1)
1.2. If not, drop out element with minimal count and insert new pair (E,1)

要素の頻度がF>0.5の場合、この手順の最後に確率(非常に大まかに、実際にははるかに高い)1-(1-F)^ Mでセットに含まれ、2回目の実行で要素の実際の頻度を計算します。 Sを設定します。

アルゴリズムb。配列のランダムに選択された要素の長さMのNシリーズを取り、任意の方法で最も頻度の高い要素を選択し、その頻度と一連の中間頻度を計算します。頻度計算の最大誤差は
F(realFrequency)/ sqrt(N)になります。 。したがって、F_e * 1 --1.0 / sqrt(N))> 0.5の場合、最も頻度の高い要素が見つかります。F_e(1 + 1.0 / sqrt(N))<0.5の場合、この要素は存在しません。F_eは推定頻度です。

于 2013-02-13T08:42:28.840 に答える
-2

私の頭に浮かぶ解決策の1つは、この配列から最初の要素を選択し、リストと、別の配列リストに配置したすべての一致する要素をトラバースします。次に、元のリストから2番目の要素を選択し、それを比較します。最初にそれらが等しい場合は、この要素を残して次の要素を選択します。これは可能な解決策である可能性があります。

于 2013-02-13T04:50:45.513 に答える