ハッシュ関数はなぜ素数モジュラスを使用する必要があるのですか?


335

昔、私はデータ構造の本をバーゲンテーブルから1.25ドルで購入しました。その中で、ハッシュ関数の説明は、「数学の性質」のため、最終的には素数でmodするべきだと述べていました。

1.25ドルの本に何を期待しますか?

とにかく、私は何年にもわたって数学の性質について考えてきましたが、それでもそれを理解することはできません。

素数のバケットがある場合でも、数の分布は本当にもっと多いのでしょうか?それとも、他の誰もがそれを受け入れるので、これは誰もが受け入れる古いプログラマーの物語ですか?


1
完全に合理的な質問:なぜ素数のバケットが必要なのですか?
ドラえもん2009

1
この質問は、コンピューターサイエンスに属している可能性が高いため、トピックから外れているようです。
オービットのライトネスレース2014

2
cs.stackexchange.com/a/64191/64222別のよく説明された説明。
グリーンツリー


ここではいくつかの驚くべき証拠番号と多少関連する質問に別の偉大な説明です- quora.com/...
AnBisw

回答:


242

通常、単純なハッシュ関数は、入力(文字列の場合は文字)の「コンポーネント部分」を取得し、定数の累乗で乗算して、整数型に加算します。たとえば、文字列の典型的な(特に良いわけではありませんが)ハッシュは次のようになります。

(first char) + k * (second char) + k^2 * (third char) + ...

次に、最初の文字がすべて同じ文字列の束が入力されると、少なくとも整数型がオーバーフローするまで、結果はすべてkを法として同じになります。

[例として、Javaの文字列hashCodeは不気味にこれに似ています-k = 31で文字を逆順にします。したがって、同じ方法で終了する文字列間で31を法とする印象的な関係が得られ、最後を除いて同じである文字列間で2 ^ 32を法とする印象的な関係が得られます。これはハッシュテーブルの振る舞いを深刻に台無しにすることはありません。]

ハッシュテーブルは、バケットの数に対するハッシュの係数を取得することで機能します。

衝突はハッシュテーブルの効率を低下させるため、可能性のあるケースでは衝突を発生させないことがハッシュテーブルで重要です。

さて、誰かがすべての最初の文字が同じであるように、アイテム間に何らかの関係がある値全体をハッシュテーブルに入れたとします。これはかなり予測可能な使用パターンであると私は言うので、あまりにも多くの衝突を発生させたくありません。

「数学の性質のため」、ハッシュで使用される定数とバケットの数が互いに素であれば、いくつかの一般的なケースでは衝突が最小限に抑えられます。彼らが素数でない場合の場合、衝突が最小化されない入力間にはかなり単純な関係がいくつかあります。すべてのハッシュは共通係数を法として等しい値で出力されます。つまり、すべてのハッシュは、共通係数を法としてその値を持つバケットの1 / n番目に分類されます。衝突はn倍になります。nは共通の要素です。nは少なくとも2であるため、かなり単純なユースケースでは、通常の2倍以上の衝突を生成することは許容できません。一部のユーザーがディストリビューションをバケットに分割する場合、単純な予測可能な使用法ではなく、異常な事故にしたいと考えています。

現在、ハッシュテーブルの実装は、それらに入れられるアイテムを制御できません。彼らはそれらが関連しているのを防ぐことはできません。したがって、行うべきことは、定数とバケット数が素数であることを確認することです。そうすることで、「最後の」コンポーネントだけに依存して、いくつかの小さな共通因子に関するバケットの係数を決定することはありません。私が知る限り、これを達成するために彼らは素数である必要はありません、ただ素数にしてください。

しかし、ハッシュ関数とハッシュテーブルが独立して書かれている場合、ハッシュテーブルはハッシュ関数がどのように機能するかを知りません。係数が小さい定数を使用している可能性があります。運が良ければ、動作はまったく異なり、非線形になる可能性があります。ハッシュが十分であれば、バケット数は問題ありません。しかし、偏執的なハッシュテーブルは良いハッシュ関数を想定できないため、素数のバケットを使用する必要があります。同様に、偏執的なハッシュ関数は、誰かが偶然に定数と共通の要素を持ついくつかのバケットを使用する可能性を減らすために、大きな素数定数を使用する必要があります。

実際には、バケットの数として2の累乗を使用するのはごく普通のことだと思います。これは便利であり、適切な大きさの素数を検索したり事前に選択したりする必要がなくなります。したがって、ハッシュ関数を使用して乗数さえも使用しないようにします。これは一般に安全な仮定です。ただし、上記のようなハッシュ関数に基づいて、時折悪いハッシュ動作が発生する可能性があり、プライムバケット数がさらに役立つ場合があります。

「すべてが素数でなければならない」という原則を説明することは、私が知る限り、ハッシュテーブル上で適切に分散するための十分条件ですが、必要条件ではありません。これにより、他のユーザーが同じルールに従っていると想定する必要なく、誰もが相互運用できます。

[編集:素数のバケットを使用する別のより特別な理由があります。これは、線形プローブで衝突を処理する場合です。次に、ハッシュコードからストライドを計算します。そのストライドがバケットカウントの要素であることが判明した場合は、最初に戻る前に(bucket_count / stride)プローブしか実行できません。もちろん、最も避けたいケースはストライド= 0です。これは特殊なケースでなければなりませんが、特殊なケースであるbucket_count / strideが小さな整数に等しいことを避けるには、bucket_countを素数にして、ストライドは、0でない場合に提供されます。]


余談

9
これは素晴らしい答えです。これについてさらに説明してください。「31を法とする文字列間で同じように終了する驚くべき関係と、2 ^ 32を法とする文字列間で2を法とする印象的な関係が、末尾付近を除いて同じになります。これは、ハッシュテーブルの動作を著しく台無しにするものではありません。 」私は特に2 ^ 32の部分を理解していません
通常の

2
これについてより明確にするための追加の注記:「すべてのハッシュは共通因子を法として等しくなります」->これは、例のハッシュ関数hash = 1st char + 2nd char * k + ...を考えると、そして最初の文字が同じ文字列を取得します。これらの文字列のハッシュ%kは同じになります。Mがハッシュテーブルのサイズで、gがMとkのgcdである場合、(hash%k)%gはhash%gに等しく(gはkを除算するため)、hash%gもこれらの文字列で同じになります。(hash%M)%gを考えます。これはhash%gと同じです(gがMを除算するため)。(hash%M)%gはこれらすべての文字列で同じです。
Quark

1
@DanielMcLaury Joshua Bloch がJavaの理由説明しました-これは2つの人気のある本(K&R、Dragon本)で推奨されており、英語の辞書で衝突が少ない状態でうまく機能しました。高速です(ホーナーの方法を使用)。どうやらK&Rでさえそれがどこから来たのか覚えていません。同様の機能は、Rabin-Karpアルゴリズム(1981)からのRabinフィンガープリントですが、K&R(1978)はそれよりも古いと考えています。
ベイン

1
@SteveJessop、「末尾近くを除いて同じである文字列間の2 ^ 32を法とする関係のストライキング」について説明していただけますか?ありがとう。
Khanna111 2017

29

ハッシュテーブルから挿入/受信するときに最初に行うことは、指定されたキーのhashCodeを計算し、hashCode%table_lengthを実行してhashCodeをhashTableのサイズにトリミングすることで正しいバケットを見つけることです。あなたがたぶんどこかで読んだ2つの「ステートメント」は次のとおりです

  1. table_lengthに2のべき乗を使用する場合、(hashCode(key)%2 ^ n)の検索は(hashCode(key)&(2 ^ n -1))と同じくらい簡単で迅速です。ただし、特定のキーのhashCodeを計算する関数が適切でない場合、いくつかのハッシュバケットに多数のキーがクラスター化されることは間違いなくありません。
  2. ただし、table_lengthに素数を使用すると、わずかにバカなhashCode関数がある場合でも、計算されたhashCodeが異なるハッシュバケットにマッピングされる可能性があります。

そしてここに証明があります。

hashCode関数の結果が他の{x、2x、3x、4x、5x、6x ...}の次のhashCodeであるとすると、これらはすべてm個のバケットにクラスター化され、m = table_length / GreatestCommonFactor (table_length、x)。(これを確認/導出するのは簡単です)。これで、クラスタリングを回避するために次のいずれかを実行できます

{x、2x、3x、4x、5x、6x ...}のように、別のhashCodeの倍数であるhashCodeをあまり多く生成しないようにしてください。ただし、hashTableが数百万のエントリ。または、GreatestCommonFactor(table_length、x)を1に等しくする、つまりtable_lengthをxと互いに素にして、mをtable_lengthに等しくするだけです。また、xがほぼすべての数値である場合は、table_lengthが素数であることを確認してください。

から-http://srinvis.blogspot.com/2006/07/hash-table-lengths-and-prime-numbers.html


11

http://computinglife.wordpress.com/2008/11/20/why-do-hash-functions-use-prime-numbers/

写真もあり、かなり明確な説明。

編集:要約として、選択した素数を値に掛けてそれらをすべて足し合わせると一意の値が得られる可能性が最も高いため、素数が使用されます。たとえば、文字列が指定されている場合、各文字の値に素数を掛けてからそれらをすべて加算すると、ハッシュ値が得られます。

より良い質問は、なぜ正確に31なのでしょうか?


5
要約は役立つと思いますが、そのサイトが死んでしまった場合に備えて、そのコンテンツの一部がここに保存されます。
Thomas Owens、

2
記事は理由を説明していませんが、「31の素数を使用すると、キーの分散が改善され、衝突の数が少なくなることが研究者により判明しました。理由は誰にもわかりません...」おかしい、私と同じ質問をしている。
theschmitzer 2009

>より良い質問は、なぜ正確に31なのでしょうか?なぜ31が使用されているのかを意味する場合、ポイントする記事はその理由を示しています。つまり、byとmultisのテストは迅速であり、cosテストはそれが使用に最適であることを示しています。私が見た他の一般的な乗数は33で、これは速度の問題が(少なくとも最初は)重要な要素であったという理論に重みを与えます。つまり、テストでそれをより良くする31については何でしょうか、それから私は知りません。
sgmoore 2009

正確に言えば、乗算器として使用できる唯一の理由は、乗算が簡単だったからです。(私が33が乗数として使用されたのを見たと私が言ったとき、私は最近を意味しません、これはおそらく数十年前であり、多くの分析がハッシュで行われる前に可能でした)。
sgmoore 2009

3
@SteveJessop 31という数値は、CPUによって(x * 32)-1演算として簡単に最適化されます。これ*32は、単純なビットシフト、またはさらに優れた即時アドレススケール係数(lea eax,eax*8; leax, eax,eax*4x86 / x64など)です。ですから*31、素数乗算の良い候補です。これは数年前にはほぼ真実でした-現在の最新のCPUアーキテクチャはほぼ瞬時に乗算を行っています-除算は常に遅いです...
Arnaud Bouchez

10

tl; dr

index[hash(input)%2]すべての可能なハッシュの半分と値の範囲で衝突が発生します。 index[hash(input)%prime]すべての可能なハッシュのうち<2の衝突になります。除数をテーブルサイズに固定すると、その数がテーブルより大きくなることもなくなります。


1
2は素数です
Ganesh Chowdhary Sadanala '25年

8

素数が使用されるのは、Pを法とする多項式を使用する一般的なハッシュ関数の一意の値を取得する可能性が高いためです。たとえば、長さが<= Nの文字列にそのようなハッシュ関数を使用すると、衝突が発生します。これは、2つの異なる多項式がPを法として同じ値を生成することを意味します。これらの多項式の差は、同じ次数N(またはそれ以下)の多項式です。根はN個以下です(これは、この主張がフィールド上の多項式=>素数にのみ当てはまるため、ここでは数学の性質が示しています)。したがって、NがPよりもはるかに小さい場合は、衝突がない可能性があります。その後、実験により、37は長さが5〜10の文字列のハッシュテーブルの衝突を回避するのに十分な大きさであり、計算に使用するには十分に小さいことがおそらくわかるでしょう。


1
説明は今では明らかなようですが、A.Shenの本「プログラミング:理論と問題」(ロシア語)を読んだ後、Rabinアルゴリズムの説明を参照してください。英語の翻訳が存在するかどうかわからない。
TT_ 2013年

5

別の視点を提供するために、このサイトがあります:

http://www.codexon.com/posts/hash-functions-the-modulo-prime-myth

これは、素数のバケットに切り捨てるのではなく、可能な限り最大数のバケットを使用する必要があると主張しています。それは合理的な可能性のようです。直感的には、バケットの数が多い方が良いのは確かですが、これについて数学的な議論をすることはできません。


バケット数が多いほど、衝突が少なくなります。鳩の巣の原理をご覧ください。
不明

11
@不明:それが本当だとは思いません。私が間違っている場合は修正してください。ただし、ピジョンホールの原則をハッシュテーブルに適用すると、ビンよりも要素の数が多い場合にのみ衝突が発生すると主張でき、衝突の量や密度に関する結論を導き出すことはできません。ただし、ビンの数が多い方が正しいルートだと私はまだ信じています。
Falaina

衝突がすべての意図と目的のためにランダムであると想定する場合、誕生日のパラドックスによって、より大きなスペース(バケット)により、衝突が発生する確率が減少します。
不明

1
@Unknownは、衝突がハッシュ関数自体にも依存することをお見逃しました。したがって、has機能が本当に悪い場合、サイズを大きくしても、衝突がかなり発生する可能性があります
Suraj Chandran

元の記事はなくなったようですが、元の著者との議論を含め、ここには洞察に満ちたコメントがあります。 news.ycombinator.com/item?id=650487
Adrian McCarthy

3

素数は一意の番号です。それらはユニークです。素数と他の数の積は、素数がそれを構成するために使用されるという事実により、ユニークである(コースの素数自体ほどユニークではない)可能性が最も高くなります。このプロパティはハッシュ関数で使用されます。

文字列「Samuel」を指定すると、構成する数字または文字のそれぞれに素数を掛けてそれらを加算することにより、一意のハッシュを生成できます。これが、素数が使用される理由です。

ただし、素数の使用は古い手法です。ここで重要なのは、十分に一意のキーを生成できる限り、他のハッシュ手法にも移行できることです。http://www.azillionmonkeys.com/qed/hash.htmlに関するこのトピックの詳細については、ここに アクセスしてください

http://computinglife.wordpress.com/2008/11/20/why-do-hash-functions-use-prime-numbers/


1
ははは....実際には、2つの素数の積は、素数と他の数の積よりも「一意」になる可能性が高いのではないでしょうか。
HasaniH 2009

@Beskaここで「一意性」は再帰的に定義されているので、「非一意性」も同じ方法で定義する必要があると
思い

3

ハッシュ関数の選択に依存します。

多くのハッシュ関数は、マシンのワードサイズに対応する2の累乗を法とするいくつかの係数を掛けて、データ内のさまざまな要素を結合します(その係数は、計算をオーバーフローさせるだけで解放されます)。

データ要素を変更してもテーブル全体にデータが分散されない可能性があるため、データ要素の乗数とハッシュテーブルのサイズの間に共通の要素は必要ありません。テーブルのサイズに素数を選択した場合、そのような一般的な要素はほとんどありません。

一方、これらの要素は通常、奇数の素数で構成されているため、ハッシュテーブルに2のべき乗を使用しても安全です(たとえば、EclipseがJava hashCode()メソッドを生成するときに31を使用します)。


2

テーブルサイズ(またはモジュロの数)がT =(B * C)であるとします。入力のハッシュが(N * A * B)のような場合、Nは任意の整数にできるため、出力はうまく分散されません。nがC、2C、3Cなどになるたびに、出力が繰り返されます。つまり、出力はCの位置でのみ配布されます。ここでCは(T / HCF(table-size、hash))であることに注意してください。

この問題は、HCF 1を作成することで解消できます。素数はそのために非常に適しています。

もう1つの興味深いことは、Tが2 ^ Nの場合です。これらは、入力ハッシュの下位Nビットすべてとまったく同じ出力を提供します。すべての数は2の累乗で表すことができるので、Tを使用して任意の数のモジュロを取る場合、2以上の数の累乗を減算します。これは> = Nなので、入力に応じて特定のパターンの数を常に出力します。これも悪い選択です。

同様に、10 ^ NとしてのTも同様の理由(2進数ではなく数値の10進表記のパターン)のために悪いです。

そのため、素数を使用すると、より良い分散結果が得られる傾向があるため、テーブルサイズに適しています。


2

私の他の回答https://stackoverflow.com/a/43126969/917428からコピーします。詳細と例については、こちらをご覧ください。

ベース2でコンピューターが動作するという事実に関係していると思います。ベース10で同じことがどのように機能するかを考えてみてください。

  • 8%10 = 8
  • 18%10 = 8
  • 87865378%10 = 8

数が何であってもかまいません。8で終わる限り、モジュロ10は8になります。

十分に大きな2のべき乗ではない数値を選択すると、ハッシュ関数が実際にはすべての入力ビットのサブセットではなく、すべての入力ビットの関数になります。


1

スティーブ・ジェソップの答えに何か付け加えたいと思います(評判が足りないのでコメントできません)。しかし、私はいくつかの役立つ資料を見つけました。彼の答えは非常に役立ちますが、彼は誤りを犯しました。バケットサイズは2の累乗であってはなりません。263ページのThomas Cormen、Charles Leisersenなどによる「アルゴリズムの概要」の本から引用します。

除算法を使用する場合、通常、mの特定の値を避けます。たとえば、m = 2 ^ pの場合、h(k)はkの最下位のpビットに過ぎないため、mは2のべき乗であってはなりません。すべての低次のpビットパターンが等しく可能性があることがわかっている場合を除き、ハッシュ関数をキーのすべてのビットに依存するように設計することをお勧めします。演習11.3-3で表示するように求められたため、kが基数2 ^ pで解釈される文字列である場合、m = 2 ^ p-1を選択することは適切ではありません。kの文字を置換してもハッシュ値は変更されないためです。

それが役に立てば幸い。


0

ハッシュ関数では、コリジョンを最小限に抑えることが重要であるだけでなく、数バイトを処理しながら同じハッシュにとどまることを不可能にすることが重要です。

あなたが方程式を持っているとしましょう: (x + y*z) % key = x0<x<key0<z<key。keyが素数である場合、n * y = keyはNのnごとにtrueになり、他のすべての数値に対してfalseになります。

keyが素数ではない例:x = 1、z = 2、key = 8 key / z = 4は自然数なので、4は方程式の解となり、この場合(n / 2) * y = keyはNのnごとに真です。8は素数ではないため、方程式の解の量は実質的に2倍になっています。

攻撃者がすでに8が方程式の可能な解決策であることを知っている場合、ファイルを8から4に変更しても、同じハッシュを取得できます。


0

上記の人気のある回答の上部にリンクされている人気のワードプレスのウェブサイトを読みました。私が理解したことから、私が行った簡単な観察を共有したいと思います。

詳細については、こちらの記事をご覧ください。ただし、次のことが当てはまると想定しています。

  • 素数を使用すると、一意の値の「最良の可能性」が得られます

一般的なハッシュマップの実装では、2つのことを一意にする必要があります。

  • キーの一意のハッシュコード
  • 実際のを格納する一意のインデックス

どうやって一意のインデックスを取得するにはよいですか?内部コンテナの初期サイズも素数にすることで。つまり、基本的に、primeが関係するのは、IDオブジェクトに使用し、内部コンテナー内のインデックスを見つけるという、固有の番号を生成するという固有の特性を持っているためです。

例:

key = "key"

値= "値" uniqueId = "k" * 31 ^ 2 + "e" * 31 ^ 1` + "y"

一意のIDにマップします

今、私たちは価値のためにユニークな場所を望んでいます-それで私たちは

uniqueId % internalContainerSize == uniqueLocationForValue、仮定internalContainerSizeも素数です。

私はこれが単純化されていることを知っていますが、私は一般的な考えを通過したいと思っています。


0

素数べき係数に関する「数学の性質」は、それらが有限体の 1つのビルディングブロックであることです。他の2つのビルディングブロックは、加算と乗算の演算です。素数係数の特別な特性は、それらが「正規の」加算および乗算演算で有限体を形成することであり、係数に適用されます。これは、すべての乗算が素数を法とする異なる整数にマッピングされるため、すべての加算が行われることを意味します。

素数係数は次の理由で有利です。

  • 二次ハッシュで二次乗数を選択するときに最も自由になります。0を除くすべての乗数は、最終的にすべての要素に1回だけアクセスします。
  • すべてのハッシュが係数よりも小さい場合、衝突はまったくありません。
  • ランダムな素数は2つの係数の累乗よりもよく混合し、サブセットだけでなくすべてのビットの情報を圧縮します

ただし、これらには大きな欠点があり、整数の除算が必要です。これは、最近のCPUでも、多くの(〜15-40)サイクルかかります。約半分の計算で、ハッシュが非常によく混ざっていることを確認できます。2つの乗算とxorshift演算は、プライムモドゥルスよりもよく混合されます。次に、どのハッシュテーブルサイズも使用でき、ハッシュリダクションは最も高速です。2つのテーブルサイズの合計で合計7つの演算が行われ、任意のサイズで約9つの演算が実行されます。

最近、最速のハッシュテーブル実装の多くを調べましたが、それらのほとんどは素数モジュライを使用していません。


0

この質問は、ハッシュテーブルが2の累乗ではなく、素数サイズの配列を使用する必要がある理由というより適切な質問とマージされました。 、glibcのように、素数サイズの配列を使用します。まだありません。

一般に、2つのテーブルの累乗ははるかに高速です。サイズがnの(「先行ゼロのカウント」)をh % n => h & bitmask介してビットマスクを計算できる高価ながありclzます。モジュロ関数は、論理よりも約50倍遅い整数除算を行う必要がありますand。Lemireのhttps://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/を使用するなど、モジュロを回避するためのいくつかのトリックがありますが、一般的に高速ハッシュテーブルはパワーを使用しますの2、および安全なハッシュテーブルは素数を使用します。

なんでそうなの?

この場合のセキュリティは、衝突解決戦略への攻撃によって定義されます。これは、ほとんどのハッシュテーブルでは、リンクされた衝突リスト内の単なる線形検索です。または、より高速なオープンアドレッシングテーブルを使用して、テーブルを直接線形検索します。したがって、2つのテーブルの累乗と、JSONインターフェースによって提供されるキーのリストのサイズや順序など、テーブルに関するいくつかの内部知識があれば、使用される正しいビットの数を取得できます。ビットマスク上の1の数。これは通常10ビット未満です。また、5〜10ビットの場合、最強のハッシュ関数と最も遅いハッシュ関数を使用しても、ブルートフォースコリジョンは簡単です。32ビットまたは64ビットのハッシュ関数の完全なセキュリティはもう得られません。そしてポイントは、高速な小さなハッシュ関数を使用することであり、つぶやきや怪物などのモンスターではありません。

したがって、DNSリゾルバやプログラミング言語など、ハッシュテーブルへの外部インターフェイスを提供する場合は、そのようなサービスをDOS化するのが好きな悪用者を気にする必要があります。そのような人々にとって、はるかに簡単な方法であなたの公共サービスをシャットダウンすることは通常より簡単ですが、それは実際に起こりました。だから人々は気にしました。

したがって、このような衝突攻撃を防ぐための最良の選択肢は、

1)プライムテーブルを使用する

  • バケットの検索には、32ビットまたは64ビットすべてが重要であり、数ビットだけではありません。
  • ハッシュテーブルのサイズ変更関数は、単なるdoubleよりも自然です。最良の成長関数はフィボナッチ数列であり、素数は2倍よりもそれに近づきます。

2)実際の攻撃に対してより優れた対策を使用し、2つのサイズの高速パワーを使用します。

  • 衝突をカウントし、検出された攻撃で中断またはスリープします。これは、確率が1%未満の衝突数です。32ビットのハッシュテーブルを持つ100のように。これは、たとえばdjbのdnsリゾルバが行うことです。
  • 衝突攻撃が検出された場合、衝突のリンクリストをO(log n)ではなくO(log n)検索でツリーに変換します。これは、たとえばjavaが行うことです。

私が説明したように、より安全なハッシュ関数がそのような攻撃を防ぐのを助けるという広く通じた神話があります、それは間違っています。低ビットのみではセキュリティはありません。これは素数サイズのテーブルでのみ機能しますが、これは2つの最も遅いメソッドの組み合わせ、つまり低速ハッシュと低速素数モジュロを使用します。

ハッシュテーブルのハッシュ関数は、主に小さく(傾斜可能)かつ高速である必要があります。セキュリティは、衝突での線形検索を防ぐことからのみ得ることができます。また、一部の値に影響されないような(乗算を使用する場合の\ 0など)のような、ひどく悪いハッシュ関数を使用しないでください。

ランダムシードを使用することも良い選択肢です。人々は最初にそれを使い始めましたが、テーブルの十分な情報があれば、ランダムシードでもあまり役に立たず、動的言語は通常、他の方法でシードを取得するのは簡単です。既知のメモリ位置。


-1
function eratosthenes(n) {

    function getPrime(x) {
        var middle = (x-(x%2))/2;
        var arr_rest = [];
        for(var j=2 ; j<=middle;j++){
            arr_rest.push(x%j);
        }

        if(arr_rest.indexOf(0) == -1) {
            return true
        }else {
            return false
        }

    }
    if(n<2)  {
        return []
    }else if(n==2){
        return [2]
    }else {
        var arr = [2]
        for(var i=3;i<n;i++) {
            if(getPrime(i)){
                arr.push(i)
            }
        }
    }

    return arr;
}

2
ソリューションを説明するコメントを追加できますか?
pom421
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.