Từ nhận xét ban đầu của tôi: Điều này liên quan chặt chẽ đến một số lượng phổ biến trong đánh giá năng suất học tập, chỉ số Hirsh, được gọi là -indexh . Nói tóm lại, nó được định nghĩa là số lượng ấn phẩm người ta có sao cho mỗi trong số họ có ít nhất h trích dẫn ( h lớn nhất như vậy ).hhh
Cách duy nhất để vấn đề của bạn khác biệt là bạn sẽ quan tâm không chỉ về việc có bao nhiêu ấn phẩm thỏa mãn tiêu chí mà còn cả số lượng trích dẫn của chúng , nhưng đó là một sửa đổi nhỏ. Dữ liệu đã có, thuật toán ban đầu chỉ cần bỏ nó.
Tính toán được thực hiện nói chung khá đơn giản và đồng ý với câu trả lời của Karolis Juodelė .
Cập nhật: Tùy thuộc vào kích thước và đặc tính của dữ liệu của bạn, có thể đáng để khám phá các phương pháp sắp xếp một phần mảng bằng cách lọc dữ liệu ở trên và dưới điểm then chốt (quicksort xuất hiện trong tâm trí). Sau đó, tùy thuộc vào việc có quá ít hay quá nhiều điều chỉnh trục và làm lại trên tập hợp con có chứa nó hay không. Bạn không cần một trật tự giữa các yếu tố cao hơn và chắc chắn không phải giữa các yếu tố thấp hơn thế. Vì vậy, ví dụ, khi bạn tìm thấy tất cả các phần tử lớn hơn hoặc bằng h 1 và có ít hơn h 1 trong số chúng, bạn không cần phải chạm vào tập hợp con đó một lần nữa, chỉ cần thêm vào nó. Điều này chuyển đổi đệ quy vốn có thành quicksort thành đệ quy đuôi và do đó có thể được viết lại thành một vòng lặp.hh1h1
Haskell của tôi hơi gỉ nhưng điều này sẽ làm những gì tôi mô tả ở trên và dường như hoạt động. Hy vọng nó có thể được hiểu ở một mức độ nào đó, tôi rất vui khi được giải thích thêm.
-- just a utility function
merge :: [a] -> [a] -> [a]
merge [] ys = ys
merge (x:xs) ys = x : merge xs ys
-- the actual implementation
topImpl :: [Int] -> [Int] -> [Int]
topImpl [] granted = granted
topImpl (x:xs) granted
| x == (1 + lGreater + lGranted) = x : merge greater granted
| x > (1 + lGreater + lGranted) = topImpl smaller (x : merge greater granted)
| otherwise = topImpl greater granted
where smaller = [y | y <- xs, y < x]
greater = [y | y <- xs, y >= x]
lGreater = length greater
lGranted = length granted
-- starting point is: top of whole array, granted is empty
top :: [Int] -> [Int]
top arr = topImpl arr []
Ý tưởng là thu thập granted
những gì bạn biết chắc chắn sẽ tham gia vào kết quả, và không sắp xếp nó thêm nữa. Nếu greater
cùng với sự x
phù hợp, chúng ta may mắn, nếu không, chúng ta cần thử với một tập hợp nhỏ hơn. (Các trục x
chỉ đơn giản là bất cứ điều gì đã xảy ra là mục đầu tiên của sublist rằng hiện đang xem xét.) Lưu ý rằng lợi thế đáng kể so với dùng các yếu tố lớn nhất từng người một là chúng ta làm điều này trên các khối kích thước trung bình và không cần sắp xếp chúng thêm.r e m a i n i n g/ 2
Thí dụ:
Hãy lấy bộ của bạn [1,3,4,1,3,6]
.
x = 1
, granted = []
, greater = [3,4,1,3,6]
. Ouch, chúng tôi đã gặp một trường hợp bệnh lý khi trục quá nhỏ (thực sự quá nhỏ mà smaller
trống) ngay trong bước đầu tiên. May mắn là algo của chúng tôi đã sẵn sàng cho điều đó. Nó loại bỏ x
và thử lại với greater
một mình.
x = 3
, granted = []
, greater = [4,3,6]
. Cùng nhau, chúng tạo thành một mảng có độ dài 4 nhưng chúng ta chỉ có giới hạn từ bên dưới 3 nên quá nhiều. Lặp lại greater
một mình.
x = 4
, granted = []
, greater = [6]
. Điều này cung cấp cho một mảng gồm 2 phần tử 4 mỗi phần, dường như chúng ta có thể đã sử dụng cho một số phần tử nữa. Giữ cái này và lặp lại smaller = [3]
.
x = 3
, granted = [4,6]
, greater = []
. Điều này cùng nhau cung cấp một mảng gồm 3 phần tử ≥ 3 mỗi phần, vì vậy chúng tôi có giải pháp của chúng tôi [3,4,6]
và chúng tôi có thể quay lại. (Lưu ý rằng hoán vị có thể thay đổi tùy theo thứ tự đầu vào, nhưng sẽ luôn chứa các điều khoản cao nhất có thể, không bao giờ [3,3,6]
hoặc [3,3,4]
cho ví dụ của bạn.)
(Btw. Lưu ý rằng sự đệ quy thực sự đã sụp đổ theo một chu kỳ.) Sự phức tạp có phần tốt hơn so với quicksort vì có nhiều so sánh được lưu:
Trường hợp tốt nhất (ví dụ [2,2,1,1,1,1]): một bước so sánh , n - 1
Trường hợp trung bình: bước, so sánh O ( n ) trong tổng sốO ( nhật kýn )Ô ( n )
nÔ ( n2)
Có một vài so sánh không cần thiết trong đoạn mã trên, như tính toán smaller
xem chúng ta có cần nó hay không, chúng có thể được gỡ bỏ dễ dàng. (Tôi nghĩ rằng đánh giá lười biếng sẽ quan tâm đến điều đó mặc dù.)