Saya telah diberikan pertanyaan wawancara ini:
Diberikan file input dengan empat miliar bilangan bulat, berikan algoritma untuk menghasilkan bilangan bulat yang tidak terkandung dalam file. Asumsikan Anda memiliki memori 1 GB. Tindak lanjuti apa yang akan Anda lakukan jika Anda hanya memiliki 10 MB memori.
Analisis saya:
Ukuran file adalah 4 × 10 9 × 4 byte = 16 GB.
Kita dapat melakukan penyortiran eksternal, sehingga memberi tahu kita kisaran bilangan bulat.
Pertanyaan saya adalah apa cara terbaik untuk mendeteksi bilangan bulat yang hilang dalam rangkaian bilangan bulat besar yang diurutkan?
Pemahaman saya (setelah membaca semua jawaban):
Dengan asumsi kita berbicara tentang bilangan bulat 32-bit, ada 2 32 = 4 * 10 9 bilangan bulat yang berbeda.
Kasus 1: kami memiliki 1 GB = 1 * 10 9 * 8 bit = 8 miliar bit memori.
Larutan:
Jika kita menggunakan satu bit yang mewakili satu integer yang berbeda, itu sudah cukup. kita tidak perlu menyortir.
Penerapan:
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);
}
}
}
Kasus 2: 10 MB memori = 10 * 10 6 * 8 bit = 80 juta bit
Larutan:
Untuk semua kemungkinan awalan 16-bit, ada 2 16 jumlah bilangan bulat = 65536, kita membutuhkan 2 16 * 4 * 8 = 2 juta bit. Kita perlu membangun 65536 ember. Untuk setiap bucket, kita membutuhkan 4 byte yang menyimpan semua kemungkinan karena kasus terburuk adalah semua 4 miliar bilangan bulat milik bucket yang sama.
- Buat konter setiap bucket melalui pass pertama melalui file.
- Pindai ember, temukan yang pertama yang memiliki kurang dari 65536 hit.
- Bangun bucket baru dengan awalan 16-bit yang tinggi, kami temukan di langkah 2 hingga pass kedua file
- Pindai ember yang ada di langkah 3, temukan ember pertama yang tidak memiliki hit.
Kode ini sangat mirip dengan yang di atas.
Kesimpulan: Kami mengurangi memori melalui peningkatan pass file.
Klarifikasi untuk mereka yang datang terlambat: Pertanyaan, seperti yang ditanyakan, tidak mengatakan bahwa ada tepat satu bilangan bulat yang tidak terdapat dalam file — setidaknya itu bukan cara kebanyakan orang mengartikannya. Banyak komentar di thread komentar yang tentang itu variasi tugas, meskipun. Sayangnya komentar yang memperkenalkannya ke utas komentar kemudian dihapus oleh penulisnya, jadi sekarang sepertinya balasan yatim untuk itu hanya salah mengerti segalanya. Sangat membingungkan, maaf.