Bằng văn bản một số mã ngày hôm nay, tôi đã xảy ra khi một hoàn cảnh đã khiến tôi viết một tìm kiếm nhị phân của một loại mà tôi chưa bao giờ thấy trước đây. Liệu tìm kiếm nhị phân này có một tên, và nó thực sự là một tìm kiếm "nhị phân"?Có tên nào cho loại tìm kiếm nhị phân này không?
Động lực
Trước hết, để làm cho việc tìm kiếm dễ dàng hơn để hiểu, tôi sẽ giải thích các trường hợp sử dụng mà sinh ra sự sáng tạo của mình.
Giả sử bạn có danh sách các số có thứ tự. Bạn được yêu cầu tìm chỉ mục của số trong danh sách gần nhất với x.
int findIndexClosestTo(int x);
Các cuộc gọi đến findIndexClosestTo()
luôn theo quy tắc này:
Nếu kết quả cuối cùng của
findIndexClosestTo()
lài
, sau đó chỉ số gần gũi hơn vớii
đã xác xuất cao hơn là kết quả của cuộc gọi hiện tại đểfindIndexClosestTo()
.
Nói cách khác, chỉ mục chúng tôi cần tìm thời gian này có nhiều khả năng gần hơn với lần cuối chúng tôi tìm thấy gần hơn so với lần cuối chúng tôi tìm thấy.
Ví dụ: hãy tưởng tượng một cậu bé được mô phỏng đi bên trái và bên phải trên màn hình. Nếu chúng ta thường truy vấn chỉ mục vị trí của cậu bé, có khả năng anh ấy ở đâu đó gần nơi cuối cùng chúng tôi tìm thấy anh ấy.
Algorithm
Với trường hợp trên, chúng ta biết kết quả cuối cùng của findIndexClosestTo()
là i
(nếu điều này thực sự là lần đầu tiên các chức năng đã được gọi là, i
mặc định là chỉ số giữa của danh sách, vì đơn giản, mặc dù một tìm kiếm nhị phân riêng biệt để tìm kết quả của cuộc gọi đầu tiên thực sự sẽ nhanh hơn), và hàm này đã được gọi lại. Căn cứ vào số điện thoại mới x
, chúng tôi làm theo thuật toán này để tìm chỉ số của nó:
interval = 1;
- Sản phẩm số chúng ta đang tìm kiếm,
x
, đặt ởi
? Nếu có, hãy trả lạii
; - Nếu không, hãy xác định xem
x
ở trên hoặc bên dướii
. (Hãy nhớ rằng, danh sách được sắp xếp.) - Di chuyển
interval
chỉ mục theo hướngx
. - Nếu chúng tôi đã tìm thấy
x
tại vị trí mới của chúng tôi, hãy trả lại vị trí đó. - Double
interval
. (Ví dụinterval *= 2
) - Nếu chúng ta đã trôi qua
x
, quay trở lạiinterval
chỉ số, thiết lậpinterval = 1
, đi đến 4.
Với quy tắc xác xuất đã nêu ở trên (dưới tiêu đề Động lực), điều này dường như tôi trở thành cách hiệu quả nhất để tìm chỉ mục chính xác. Bạn có biết cách nhanh hơn không?
Tôi cho rằng đây thực sự là một mảng chứ không phải danh sách? Bởi vì tìm kiếm nhị phân trên một danh sách sẽ là ngu ngốc. – Nemo
Tôi cho rằng câu trả lời tốt nhất sẽ phụ thuộc vào chính xác phân bố xác suất cho vị trí dựa trên i. ví dụ, nếu có một cơ hội 99% đó là trong vòng 3 của tôi thì một câu trả lời rất khác nhau sẽ hữu ích so với nếu nó chỉ có 0,001% có khả năng ở tôi hơn bất cứ nơi nào khác. Tôi nghĩ rằng câu trả lời tối ưu sẽ là một phân bố dựa trên xác suất sao cho tìm kiếm nhị phân chọn một điểm cung cấp 50% cơ hội của mục mong muốn ở mỗi bên. Vì vậy, nếu bạn có thể xác định đường cong xác suất, bạn có thể xác định một thuật toán khá tốt. – Chris
@Chris điểm rất tốt. Nếu tất cả các điểm dữ liệu là _nearly_ bằng nhau trong xác suất, điều này có thể sẽ tồi tệ hơn tìm kiếm nhị phân thông thường. Trong trường hợp của tôi, xác suất xuất hiện để phân rã theo cấp số nhân hơn nữa bạn nhận được từ điểm cuối cùng, trong trường hợp này, tôi tin rằng tìm kiếm này nhanh hơn. –