2009-10-29 32 views
6

Đây là số problem được mô tả trong Programming pearls. Tôi không thể hiểu được phương pháp tìm kiếm nhị phân mà tác giả đã bỏ qua. Bất kỳ ai có thể giúp xây dựng? Cảm ơn.Tìm số nguyên 32 bit bị thiếu trong một mảng chưa phân loại chứa tối đa 4 tỷ ints

EDIT: Tôi có thể hiểu tìm kiếm nhị phân nói chung. Tôi chỉ không thể hiểu làm thế nào để áp dụng tìm kiếm nhị phân trong trường hợp đặc biệt này. Làm thế nào để quyết định số bị thiếu là trong hoặc không trong một số phạm vi để chúng tôi có thể chọn một số khác. Tiếng Anh không phải là ngôn ngữ mẹ đẻ của tôi, đó là một lý do tôi không thể hiểu rõ tác giả. Vì vậy, hãy sử dụng ngôn ngữ đơn giản bằng tiếng Anh :)

EDIT: Cảm ơn tất cả các bạn đã có câu trả lời và nhận xét tuyệt vời! Bài học quan trọng nhất tôi không giải được câu hỏi này là Tìm kiếm nhị phân không chỉ áp dụng cho mảng được sắp xếp!

+0

Bạn không hiểu phần nào? Bạn có thể xây dựng? – dirkgently

+3

Tìm kiếm nhị phân là giải pháp cho một vấn đề khác. Nó không thích hợp để tìm một giá trị trong một phạm vi chưa phân loại. –

+0

Những gì bạn không thể hiểu? Tìm kiếm nhị phân ở tất cả hoặc chỉ mô tả tác giả? –

Trả lời

9

có một số chi tiết thông tin về this web site Trích dẫn từ đó:..

"đó là hữu ích để xem nhị phân này tìm kiếm theo hai mươi bit đại diện cho mỗi số nguyên. chúng tôi đọc (tối đa) một triệu số nguyên đầu vào và viết các số nguyên đó bằng bit không đầu vào một băng và những phần có bit đầu tiên đến một băng khác. Một trong hai băng có chứa tối đa 500.000 số nguyên, vì vậy chúng tôi sử dụng băng đó làm đầu vào hiện tại và lặp lại quá trình thăm dò, nhưng lần này vào bit thứ hai. Nếu băng đầu vào ban đầu chứa N phần tử, thì giá trị đầu tiên sẽ đọc N số nguyên, lần thứ hai vượt qua tối đa N/2, lần vượt qua thứ ba ở hầu hết N/4, và cứ như vậy, tổng thời gian chạy là tỷ lệ thuận với N. số nguyên còn thiếu có thể được tìm thấy bằng cách phân loại trên băng và sau đó quét, nhưng điều đó sẽ yêu cầu thời gian tỷ lệ với N log N. "

Như bạn thấy, đây là một biến thể trên thuật toán tìm kiếm nhị phân: chia thành hai phần và giải quyết vấn đề cho một trong những phần nhỏ hơn.

+0

Nếu tôi nhớ chính xác, 1 + 1/2 + 1/4 .. = Tổng (1/2^n) có xu hướng hướng tới 2. Do đó phương pháp này là phức tạp của O (2N) –

+2

Điều đó không đúng. Sự phức tạp thực sự là O (log n). Giả sử không gian vấn đề là 8 (vì vậy chúng ta cần phải tìm một số nguyên còn thiếu trong phạm vi 0,1,2,3,4,5,6,7). Điều này đòi hỏi tối đa 3 lượt của thuật toán. Nếu chúng ta tăng gấp đôi không gian vấn đề lên 16, chúng tôi yêu cầu tối đa 4 lần giải thuật. Vì vậy, mặc dù không gian vấn đề đã tăng gấp đôi từ 8 lên 16, thời gian cần để giải quyết vấn đề chỉ tăng thêm 1.33333 ... Nếu chúng ta tăng gấp đôi lần nữa, thì thời gian cần để giải quyết vấn đề chỉ tăng lên 1,25 . Điều đó có nghĩa là độ phức tạp của thuật toán không phải là tuyến tính (vì vậy không phải O (2n)). –

+7

Phút mà chúng tôi đã thực hiện một lần hoàn thành thông qua dữ liệu, độ phức tạp là O (n), vì vậy O (log (n)) là đúng. Bây giờ O (n) có nghĩa là có một số hằng số, c, sao cho thời gian chạy của thuật toán bị ràng buộc từ trên bởi c * n, vì vậy O (2n) là chính xác giống như O (n). rwwilden, sai lầm của bạn là chỉ đếm khi giá trị của một đường chuyền cũng tăng gấp đôi. –

1

Vâng, đó là về một tệp có chứa tất cả 4 tỷ số nguyên trừ một! Đó là bắt trong trường hợp này.

  1. Khi bạn di chuyển dọc theo danh sách các số nguyên, hãy tính tổng.
  2. Cuối cùng, tính tổng như thể có tất cả các số nguyên hiện tại bằng công thức N * (N + 1)/2
  3. Trích tổng tại (1) từ số tiền bạn tính tại (2). Đó là số nguyên còn thiếu.

Ví dụ: Giả sử chúng tôi có trình tự sau: 9 3 2 8 4 10 6 1 7 (1 đến 10 với 5 mất tích). Khi chúng ta thêm số nguyên tuần tự, chúng ta nhận được 9 + 3 + 2 + 8 + 4 + 10 + 6 + 1 + 7 = 50. Tổng của tất cả các số nguyên từ 1 đến 10 sẽ là 10 * (10 + 1)/2 = 55 Do đó, số nguyên còn thiếu là 55 - 50 = 5. QED

+0

Không, đó là phạm vi chưa được phân loại. Tuy nhiên, bạn đúng là có nhiều hơn một khoảng trống (vấn đề nói nhiều nhất là 4 tỷ số nguyên) –

+0

đó là về một tệp có chứa tối đa 4 tỷ số nguyên (nó có thể chứa ít hơn), tất nhiên không phải toàn bộ phạm vi của int32 . bạn phải tìm ít nhất một trong các số nguyên 32 bit không có trong tệp. –

+0

(xin lỗi về câu trả lời đã xóa, tôi đã đọc sai vấn đề quá lần đầu tiên) –

2

Tôi tin rằng tác giả đang nhận được là bạn chọn điểm giữa của phạm vi số hiện tại của mình và chuẩn bị hai tệp đầu ra. Khi bạn đọc đầu vào của mình, mọi thứ phía trên điểm giữa sẽ đi vào một tệp và mọi thứ bên dưới điểm giữa sẽ đi vào điểm khác. Sau khi kết thúc, bạn chọn bất kỳ tệp nào nhỏ hơn, và sau đó lặp lại thao tác, sử dụng [giới hạn dưới, điểm giữa] hoặc (điểm giữa, giới hạn trên) làm phạm vi mới cho đến khi tệp và phạm vi đủ nhỏ để chuyển sang mô hình bitmap (hoặc một trong các tập tin đầu ra của bạn là trống)

Damien

+0

Bằng tiêu chí nào bạn chọn nửa trên và nửa dưới? Vì các phần tử không được phân loại. –

+0

@rwwilden - Tôi không chắc tôi hiểu truy vấn của bạn? Nếu bạn đang yêu cầu một nửa bạn tiếp tục làm việc với, tôi tin rằng tôi đã trả lời (tập tin nhỏ hơn, được chỉ ra trong văn bản) –

+0

@rwwilden - Tôi nghĩ rằng tôi có thể không rõ ràng - khi tôi nói về phạm vi, và điểm giữa, tôi đã đề cập đến các giá trị số, chứ không phải vị trí của chúng trong tệp đầu vào. Về cơ bản, chúng tôi đã đăng cùng một mô tả. –

2

Ý tưởng chung là: chọn một dải số nguyên và chọn tất cả các số nguyên nằm trong phạm vi đó. Nếu số lượng số nguyên nhỏ hơn kích thước của phạm vi của bạn, bạn biết rằng phạm vi đó chứa một hoặc nhiều số bị thiếu.

Điều này áp dụng cho vấn đề ban đầu về cách bạn biết có một số số bị thiếu ở địa điểm đầu tiên.

2

Nếu bạn xem xét các số trong phạm vi từ 1 đến N; một nửa trong số chúng lớn hơn N/2 và một nửa trong số chúng nhỏ hơn N/2

Những cái lớn hơn N/2 sẽ có MSB được đặt thành một; MSB = 0 cho những cái nhỏ hơn.

phân vùng toàn bộ thiết lập dựa trên MSB mà sẽ cung cấp cho bạn hai bộ: tập hợp các số nhỏ hơn N/2 và tập hợp các số lớn hơn N/2

Các phân vùng kích thước nhỏ hơn có yếu tố thiếu .

Trong bước tiếp theo, hãy sử dụng MSB tiếp theo.

  1. Nếu các thiết lập nhỏ hơn là ít hơn N/2, một nửa trong số đó là ít hơn N/4 (2 MSB = 0) và nửa còn lại lớn hơn N/4 (2 MSB = 1)

  2. Nếu tập nhỏ hơn lớn hơn N/2, một nửa trong số đó nhỏ hơn N/2 + N/4 (2 MSB = 0) và nửa kia lớn hơn N/2 + N/4 (MSB thứ 2 = 1)

Mỗi vòng sẽ giảm một nửa không gian tìm kiếm.

Sum (N/2^i) for 0 <= i < log N gives you O(N) 
2

Đây là câu hỏi cơ bản giống như this question. Cách tiếp cận tương tự cũng hoạt động ở đây đối với trường hợp bộ nhớ phong phú để có được độ phức tạp O (N). Về cơ bản chỉ đệ quy cố gắng đặt mọi số nguyên vào vị trí chính xác của nó và xem những gì không có giá trị chính xác.

Các vấn đề liên quan