Java を使用して非常に大きなブール配列を作成しようとすると、次のようになります。
boolean[] isPrime1 = new boolean[600851475144];
精度エラーが発生する可能性がありますか?
大きすぎますか?
6000億ビットを格納するには、絶対最小アドレス空間 75ギガバイトが必要です! 頑張ってください!
さらに悪いことに、Java 仕様では、boolean
配列が要素ごとに 1 ビットのメモリを使用することを指定していません。それ以上のメモリを使用する可能性があります (場合によっては実際に使用します)。
いずれにせよ、その数はProject Euler #3から認識しています。それだけのメモリが必要な場合は、間違っています...
BitSetの使用を検討してください。
オイラー問題 #3 を間違った方法で解こうとしているので、ここにヒントがあります:特定の制限を下回るすべての素数ではなく、数値のすべての素因数を見つけることになっています。
ところで: この特定のオイラー問題は、非常に少量の RAM を使用して解決できます。
配列インデックスは long ではなく int であるため、「配列」が大きすぎて配列に収まりません。 Java Collection クラスの 1 つの方が適している場合があります。Integer.MAX_VALUE
気にしないでください - Collection.size() も int を返すため、Collection はアイテムを超える数を格納することもできません。
ええと...それは約70GB相当のブール値になります。うまくいかない。とんでもない。
配列のすべての操作を処理するクラスにカプセル化された long の配列を使用できます。BitSet の独自の実装のようなもの。
問題は、配列のサイズに long 値と int 値を使用していることです。Java は、int の最大値よりも長い配列の長さをサポートしていません。指定したサイズが int の最大値を超えていますが、long 内に収まるため、Java は長さを long として処理しています。したがって、長さを int に変換して配列を作成する必要があります。long -> int からの変換により、表示されている警告が生成されます
Apache ActiveMQには、BitArrayBinと呼ばれるデータ構造があります。これは、メッセージが重複しているかどうかを確認するために使用されます。メッセージIDは、プロデューサーIDとシーケンスIDの組み合わせです。各プロデューサーには、シーケンスIDを追跡するためのBitArrayBinがあります。指定されたプロデューサーのBitArrayBinを見つけると、長い値であるシーケンスIDをBitArrayBinに設定します。
oldValue = bitArrayBin.setBit(sequenceId, true)
if (oldVlaue) {
"message is duplicated"
}
このメソッドは古い値を返します。
yが長いインデックスの場合、binインデックスとそのインデックスへのオフセットを導出するために使用されます。
y = bin index * 64 + offset
BitArrayBinは、構築中にサイズを定義できる多くのビンのホルダーに他なりません。各ビンにはビットを格納するための長い変数が含まれているため、最大64個のブール値を格納できます。
ビットマスキングは、ビットを設定し、その値を取得するために使用されます。
このクラスには多くのドキュメントがありません。内部を知るには、そのソースコードを調べる必要があります。
値をファイルに保存してから、ファイル内の位置を探して正しい値を取得してみませんか。他の人が述べたように、それは70GBのデータです。ほとんどの場合、それをメモリに保持することさえできません。ファイルに保存する場合は、ビットごとの演算子を使用してデータを保存および取得するときに個々のビットを調べて、ストレージ スペースを節約することもできます。
また、素数の数は数のサイズに応じて減少するため、素数自体を順番にファイルに保存し、その数をバイナリ検索して素数の1つであるかどうかを確認する方がよいでしょう。 .
配列にはどのような値がありますか? このように大きな数の場合、スパース配列になると思いますので、マップ/リストを使用してスペースを割り当て、1 値の値を少しだけ格納するのが最善でしょう。または、ほとんどの値が 1 になる場合は 0 の値を指定します。