quá trình Hôi cấp bách của việc sáp nhập hai ...
a = [1,3,7,11]
b = [2,4,6,14]
c = merge_sorted_arrays(a,b)
def merge_sorted_arrays(a,b)
a.reverse!
b.reverse!
output = []
loop do
break if a.empty? || b.empty?
output << (a.last < b.last ? a.pop : b.pop)
end
return output + a.reverse + b.reverse
end
Có thể sử dụng .slice! để lấy yếu tố đầu tiên sẽ tốt hơn đảo ngược và popping?
====================
sửa sau khi bình luận thứ tư:
Phải rồi ... Tôi đã chơi khác , nhưng cần phải tiếp tục với công việc thực sự hoặc tôi sẽ bị sa thải ;-)
Trên một mảng lớn các số nguyên, phương pháp gốc của tôi hoạt động nhanh hơn sử dụng sort_by, nhưng sau khi điền các mảng với 100.000 đối tượng OpenStruct và sắp xếp trên một thuộc tính, sort_by nhanh gấp 100 lần.
Dưới đây là kết quả điểm chuẩn của tôi:
def pop_merge_sorted_arrays(array1,array2)
array1.reverse!
array2.reverse!
output = []
loop do
break if array1.empty? || array2.empty?
output << (array1.last.my_field < array2.last.my_field ? array1.pop : array2.pop)
end
return output + array1.reverse + array2.reverse
end
def shift_merge_sorted_arrays(array1,array2)
output = []
loop do
break if array1.empty? || array2.empty?
output << (array1.first.my_field < array2.first.my_field ? array1.shift : array2.shift)
end
return output + array1 + array2
end
def slice_merge_sorted_arrays(array1,array2)
output = []
loop do
break if array1.empty? || array2.empty?
output << (array1.first.my_field < array2.first.my_field ? array1.slice!(0) : array2.slice!(0))
end
return output + array1 + array2
end
a=(1..100000).map{|x|OpenStruct.new(:my_field => rand)}.sort_by(:my_field)
b=(1..100000).map{|x|OpenStruct.new(:my_field => rand)}.sort_by(:my_field)
# method 1
t=Time.now;w=pop_merge_sorted_arrays(a.clone,b.clone);puts Time.now-t
# average of five runs: 185.96seconds
# method 2
t=Time.now;x=shift_merge_sorted_arrays(a.clone,b.clone);puts Time.now-t
# average of five runs: 0.77seconds
# method 3
t=Time.now;y=slice_merge_sorted_arrays(a.clone,b.clone);puts Time.now-t
# average of five runs: 8.46seconds
# method 4
t=Time.now;z=(a.clone + b.clone).sort_by(&:my_field);puts Time.now-t
# average of five runs: 2.13seconds
Vì vậy, các Kết quả cuối cùng có vẻ là bạn có thể viết một phương pháp mà sẽ xáo trộn chúng trong khi giữ gìn trật tự mà sẽ chạy khá nhanh chóng (và có lẽ một số hiệu quả hơn để bóp ra của phương pháp shift_merge, nhưng đối với lợi ích bổ sung, là nó thực sự có giá trị không chỉ bunging chúng lại với nhau và sử dụng sort_by cho sự dễ dàng của nó? :-)
Tôi hy vọng điều này không được tính như là một digression .. .
OP cho biết "Thực hiện điều này không khó" vì vậy tôi không nghĩ rằng anh ta yêu cầu bạn thực hiện nó cho anh ta.Ngoài ra, bạn có thể tránh gọi ngược lại bốn lần. –
a) vâng ... Tôi đề nghị đảo chiều là không lớn (mặc dù một lần sẽ là trên một mảng nil .. nhưng vẫn còn, đó là stinky). Tôi chủ yếu sử dụng mã như là một điểm khởi đầu có thể gợi ý về cách xáo trộn cả hai với nhau, mà không cần gọi lại để sắp xếp lại. b) Tôi đã bỏ qua "nó không khó ..." trong OP. oops - Tôi có lẽ đã không được đăng đã nhận thấy rằng, nhưng tôi nhận thấy rằng bạn thực hiện một giải pháp không quá khó ;-) – Pavling
FWIW: Tôi vừa có một fiddle với một số tiêu chuẩn thô - sử dụng ".sort_by" trên hai các mảng phần tử 100.000 số được điền ngẫu nhiên mất khoảng 0,7 giây tại đây. Sử dụng bốn cuộc gọi ".verse" như trên, hành động tương tự sẽ mất khoảng 0,3 giây. Loại bỏ các đảo ngược, và thay thế .pop với .slice! (0) mất hơn 7 giây. Trong cuộc sống thực - sort_by hoặc sắp xếp có thể sẽ đơn giản, đủ để giữ cho nó vào một dòng và không lo lắng về nó quá nhiều :-) – Pavling