Это вопрос интервью:
Учитывая входной файл с четырьмя миллиардами целых чисел, предоставьте алгоритм для генерации целого числа, которое не содержится в файле. Предположим, у вас есть 1 ГБ памяти. Следите за тем, что бы вы сделали, если у вас есть только 10 МБ памяти.
Мой анализ:
Размер файла составляет 4 × 10 9 × 4 байта = 16 ГБ.
Мы можем выполнить внешнюю сортировку, таким образом, мы узнаем диапазон целых чисел. Мой вопрос заключается в том, каков наилучший способ обнаружить отсутствующее целое число в отсортированных наборах больших целых чисел?
Мое понимание (после прочтения всех ответов):
Предположим, мы говорим о 32-разрядных целых числах. Есть 2 ^ 32 = 4 * 10 9 различных целых чисел.
Случай 1: у нас 1 ГБ = 1 * 10 9 * 8 бит = 8 миллиардов бит памяти.
Решение: если мы используем один бит, представляющий одно целое число, этого достаточно. нам не нужна сортировка. Реализация:
int radix = 8;
byte[] bitfield = new byte[0xffffffff/radix];
void F() throws FileNotFoundException{
Scanner in = new Scanner(new FileReader("a.txt"));
while(in.hasNextInt()){
int n = in.nextInt();
bitfield[n/radix] |= (1 << (n%radix));
}
for(int i = 0; i< bitfield.lenght; i++){
for(int j =0; j<radix; j++){
if( (bitfield[i] & (1<<j)) == 0) System.out.print(i*radix+j);
}
}
}
Случай 2: 10 МБ памяти = 10 * 10 6 * 8 бит = 80 миллионов бит
Решение: Для всех возможных 16-битных префиксов есть 2 ^ 16 целых чисел = 65536, нам нужно 2 ^ 16 * 4 * 8 = 2 миллиона битов. Нам нужно построить 65536 ведер. Для каждого сегмента нам нужно 4 байта, содержащих все возможности, потому что в худшем случае все 4 миллиарда целых чисел принадлежат одному и тому же сегменту.
- Постройте счетчик каждого сегмента через первый проход по файлу.
- Просканируйте ведра, найдите первого, у которого попадание менее 65536.
- Создайте новые сегменты с высокими 16-битными префиксами, которые мы нашли в шаге 2 через второй проход файла
- Просканируйте ведра, созданные в шаге 3, найдите первое ведро, которое не имеет попадания.
Код очень похож на приведенный выше.
Вывод: мы уменьшаем память за счет увеличения пропускной способности файла.
Уточнение для тех, кто прибывает с опозданием: в вопросе, который задают, не говорится, что в файле нет ровно одного целого числа - по крайней мере, не так, как его интерпретирует большинство людей. Однако многие комментарии в ветке комментариев касаются этого варианта задачи. К сожалению, комментарий, который представил его в ветку комментариев, был позже удален его автором, так что теперь он выглядит так, как будто потерянные ответы на него просто неправильно поняли все. Это очень запутанно. Сожалею.