我尝试合并两个已排序的数组,而不使用排序方法中的任何构建。这是我到目前为止所拥有的。
def merge(array_1, array_2)
i = 0
k = 0
merged_array = []
while i < array_1.count && k < array_2.count
while k < array_2.count && array_1[i] > array_2[k]
merged_array << array_2[k]
k += 1
end
merged_array << array_1[i]
i += 1
end
merged_array
end
array_1 = [5,8,9,11]
array_2 = [4,6,7,12,13]
p merge(array_1, array_2)
输入为array_1 = [5,8,9,11]
和array_2 = [4,6,7,12,13]
,输出为[4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
。有人可以解释为什么它不起作用。谢谢!
答案 0 :(得分:10)
试试这个
def merge(array_1, array_2)
return enum_for(__method__, array_1, array_2) unless block_given?
a = array_1.each
b = array_2.each
loop { yield a.peek < b.peek ? a.next : b.next }
# Your code is not working because the equivalent of these two lines
# is missing. After you reach the end of one array you have to append
# all remaining elements of the other array. I am doing this here by
# just exhausting both enumerators, one of which is empty by now.
loop { yield a.next }
loop { yield b.next }
end
p merge([5, 8, 9, 11], [4, 6, 7, 12, 13]).entries
无需跟踪指数。合并排序可以追溯到大型机和磁带的时代,因此只能使用枚举器来实现。
这是如何运作的?
each
创建枚举器peek
返回下一个元素而不推进枚举器next
通过推进枚举器StopIteration
loop
重复一段代码,直到StopIteration
被提升答案 1 :(得分:1)
可以使用Array#bsearch_index将一个数组的元素插入到另一个数组的副本中,以确定第一个数组的每个元素应该去的位置。
def merge(array_1, array_2)
array_2.each_with_object(array_1.dup) { |n,arr|
arr.insert(arr.bsearch_index { |i| i>n } || arr.size, n) }
end
array_1
#=> [5, 8, 9, 11]
array_2
#=> [4, 6, 7, 12, 13, 14]
merge(array_1, array_2)
#=> [4, 5, 6, 7, 8, 9, 11, 12, 13, 14]
这是O(n 1 * log(n 2 )),n 1 和n 2 作为两个数组的大小,所以循环越过两个数组中的较小者就会更有效。