ฉันได้รับคำถามสัมภาษณ์นี้:
ให้อินพุตไฟล์ที่มีจำนวนเต็มสี่พันล้านชุดให้อัลกอริทึมในการสร้างจำนวนเต็มซึ่งไม่ได้อยู่ในไฟล์ สมมติว่าคุณมีหน่วยความจำ 1 GB ติดตามสิ่งที่คุณจะทำถ้าคุณมีหน่วยความจำเพียง 10 MB
การวิเคราะห์ของฉัน:
ขนาดของไฟล์คือ 4 × 10 9 × 4 ไบต์ = 16 GB
เราสามารถทำการจัดเรียงภายนอกได้ดังนั้นจึงแจ้งให้เราทราบช่วงของจำนวนเต็ม
คำถามของฉันคือวิธีที่ดีที่สุดในการตรวจจับจำนวนเต็มหายไปในชุดจำนวนเต็มเรียงลำดับขนาดใหญ่?
ความเข้าใจของฉัน (หลังจากอ่านคำตอบทั้งหมด):
สมมติว่าเรากำลังพูดถึงจำนวนเต็ม 32 บิตมี 2 32 = 4 * 10 9จำนวนเต็มชัดเจน
กรณีที่ 1: เรามี 1 GB = 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 MB = 10 * 10 6 * 8 บิต = 80 ล้านบิต
สารละลาย:
สำหรับคำนำหน้า 16- บิตที่เป็นไปได้ทั้งหมดมีจำนวนเต็ม16 16 = 65536 เราต้องการ 2 16 * 4 * 8 = 2 ล้านบิต เราต้องการสร้างถัง 65536 สำหรับที่เก็บข้อมูลแต่ละชุดเราจำเป็นต้องมี 4 ไบต์เพื่อเก็บความเป็นไปได้ทั้งหมดเนื่องจากกรณีที่เลวร้ายที่สุดคือจำนวนเต็ม 4 พันล้านทั้งหมดที่อยู่ในที่เก็บข้อมูลชุดเดียวกัน
- สร้างตัวนับของที่เก็บข้อมูลแต่ละชุดผ่านการส่งผ่านครั้งแรกผ่านไฟล์
- สแกนถังหาคนแรกที่มีน้อยกว่า 65536 ครั้ง
- สร้างที่เก็บข้อมูลใหม่ซึ่งเราพบว่ามีคำนำหน้าสูง 16 บิตในขั้นตอนที่ 2 ถึงการส่งผ่านครั้งที่สองของไฟล์
- สแกนที่เก็บข้อมูลที่สร้างในขั้นตอนที่ 3 ค้นหาที่เก็บข้อมูลชุดแรกซึ่งไม่มีการเข้าชม
รหัสนี้คล้ายกับรหัสด้านบน
สรุป: เราลดหน่วยความจำผ่านการเพิ่มไฟล์ผ่าน
คำชี้แจงสำหรับผู้มาสาย: คำถามตามที่ถามไม่ได้บอกว่ามีจำนวนเต็มหนึ่งตัวที่ไม่ได้อยู่ในไฟล์อย่างน้อยนั่นไม่ใช่วิธีที่คนส่วนใหญ่ตีความมัน ความคิดเห็นจำนวนมากในหัวข้อการแสดงความคิดเห็นเป็นเกี่ยวกับรูปแบบของงานที่แม้ว่า น่าเสียดายที่ความคิดเห็นที่นำไปใช้กับเธรดความคิดเห็นถูกลบในภายหลังโดยผู้เขียนดังนั้นตอนนี้ดูเหมือนว่าการตอบกลับที่ถูกโยงถึงเพียงเข้าใจผิดทุกอย่าง มันสับสนมากขอโทษ