Как Вы делаете ДЕЙСТВИТЕЛЬНО большие булевы массивы с помощью Java?

По сути, причина, по которой optional и variant не допускают ссылочные типы, заключается в том, что существует разногласие относительно того, что присваивание (и, в меньшей степени, сравнение) должно делать для таких случаев. optional проще, чем variant показать в примерах, поэтому я буду придерживаться этого:

int i = 4, j = 5;
std::optional o = i;
o = j; // (*)

Отмеченную линию можно интерпретировать как:

  1. Rebind o, такой, что &*o == &j. В результате этой линии сами значения i и j остаются неизменными.
  2. Назначьте через o, такое &*o == &i все еще верно, но теперь i == 5.
  3. Полностью запретить назначение.

Assign-through - это поведение, которое вы получаете, просто нажимая = до = [1117], rebind - более надежная реализация и именно то, что вам действительно нужно (см. Также this вопрос , а также доклад Мэтта Калабрезе о ссылочных типах ).

Другой способ объяснить разницу между (1) и (2) заключается в том, как мы могли бы реализовать обе эти возможности извне:

// rebind
o.emplace(j);

// assign through
if (o) {
    *o = j;
} else {
    o.emplace(j);
}

Документация Boost.Optional предоставляет это обоснование:

Семантика перепривязки для назначения инициализированных необязательных ссылок была выбрана для обеспечения согласованности среди состояний инициализации даже за счет отсутствия согласованности с семантикой голых ссылок C ++. Это правда, что optional стремится вести себя как можно лучше, чем U, когда он инициализируется; но в случае, когда U равно T&, это приведет к несовместимому поведению по отношению к состоянию инициализации lvalue.

Представьте optional переадресацию присваивания ссылочному объекту (таким образом, изменяя значение ссылочного объекта, но не привязывая), и рассмотрите следующий код:

optional a = get();
int x = 1 ;
int& rx = x ;
optional b(rx);
a = b ;

Что делает присваивание?

[ 1151] Если a не неинициализирован , ответ ясен: он связывается с x (теперь у нас есть еще одна ссылка на x). Но что, если a уже инициализирован ? это изменило бы значение ссылочного объекта (что бы это ни было); что не согласуется с другим возможным случаем.

Если бы optional присваивал так же, как T&, вы никогда бы не смогли использовать присваивание Optional без явной обработки предыдущего состояния инициализации, если ваш код не способен функционировать, будь то после присваивания, a алиасирует то же самое объект как b или нет.

То есть вам нужно было бы различать, чтобы быть последовательным.

Если в вашем коде привязка к другому объекту невозможна, то весьма вероятно, что привязка в первый раз также не подходит. В таком случае присвоение неинициализированному optional должно быть запрещено. Вполне возможно, что в таком сценарии является предварительным условием, что значение lvalue должно быть уже инициализировано. Если это не так, тогда связывание в первый раз в порядке, а повторное связывание - нет, что очень маловероятно. В таком сценарии вы можете назначить само значение непосредственно, например:

assert(!!opt);
*opt=value;
blockquote>

Отсутствие соглашения о том, что должна делать эта строка, означало, что было проще просто полностью запретить ссылки , так что большая часть значений optional и variant может, по крайней мере, сделать это для C ++ 17 и начать быть полезной. Ссылки всегда могут быть добавлены позже - или так аргумент пошел. [Тысяча сто пятьдесят-пять]

9
задан iCodez 22 January 2015 в 16:11
поделиться

9 ответов

Для хранения 600 миллиардов битов Вам нужно абсолютное минимальное адресное пространство 75 гигабайтов! Удача с этим!

Еще хуже, спецификация Java не указывает это a boolean массив будет использовать единственный бит памяти для каждого элемента - это могло (и в некоторых случаях делает), используют больше.

В любом случае я распознаю что число от Euler № 3 Проекта. Если требуется так много памяти, Вы делаете его неправильно...

16
ответ дан 4 December 2019 в 06:35
поделиться

Рассмотрите использование BitSet.

4
ответ дан 4 December 2019 в 06:35
поделиться

Индекс массива является интервалом, не длинным, таким образом, Ваш "массив" является слишком большим для вписывания в массив. Один из классов Набора Java мог бы больше подойти. Не берите в голову - Collection.size () возвращает интервал также, таким образом, Набор не может сохранить больше, чем Integer.MAX_VALUE объекты также.

3
ответ дан 4 December 2019 в 06:35
поделиться

Так как Вы пытаетесь решить эйлеровую проблему № 3 неправильный путь, вот подсказка: Вы, как предполагается, находите все простые множители числа, не все простые числа ниже определенного предела.

BTW: Эта конкретная эйлерова проблема может быть решена с помощью очень небольшого количества RAM.

4
ответ дан 4 December 2019 в 06:35
поделиться

Гм... это было бы ценностью приблизительно на 70 ГБ булевских переменных. Не собирающийся работа.Ни за что.

2
ответ дан 4 December 2019 в 06:35
поделиться

Можно использовать массив longs, инкапсулировавшего в классе, который обработал бы все операции на массиве. Что-то как Ваша собственная реализация BitSet.

2
ответ дан 4 December 2019 в 06:35
поделиться

Почему не только хранят значения в файле, и затем ищут на положение в файле и тянут правильное значение. Как другие указали, это составляет 70 ГБ данных. В большинстве случаев Вы даже не смогли бы держать это в памяти. Если Вы собираетесь сохранить его в файл, Вы могли бы даже посмотреть на отдельные биты при хранении и получении данных с помощью побитовых операторов, чтобы экономить на пространстве памяти.

Кроме того, так как количество начал уменьшается с размером чисел, вероятно, лучше только сохранить сами простые числа в файле в порядке, и затем сделать двоичный поиск числа, чтобы видеть, является ли это одно из начал.

1
ответ дан 4 December 2019 в 06:35
поделиться

Проблема - Вы, используют длинное значение по сравнению с международным значением для размера массива. Java не поддерживает длины массива дольше, что максимальное значение международного Java рассматривает Вашу длину как длинное, потому что размер, который Вы указали, превышает максимальное значение для интервала, но соответствует в длинном. Следовательно это должно преобразовать длину назад в интервал для создания массива. Преобразование из длинного-> интервал производит предупреждение, что Вы видите

2
ответ дан 4 December 2019 в 06:35
поделиться

Какие значения Вы имеете в массиве? Для такого большого количества я предполагаю, что это будет разреженным массивом поэтому, возможно, было бы лучше использовать Карту/Список и просто выделить место и сохранить значение для 1 значения некоторое время. Или для 0 значений, если большинство Ваших значений будет 1.

1
ответ дан 4 December 2019 в 06:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: