我正在编写一个方法,它接受两个排序的数组,我希望它返回一个合并的数组,其中所有值都已排序。鉴于以下两个数组:
array_one = [3, 4, 8]
array_two = [1, 5, 7]
我希望我的merge_arrays方法返回:
[1, 3, 4, 5, 7, 8]
我目前的算法如下:
def merge_arrays(array_one, array_two)
merged_array_size = array_one.length + array_two.length
merged_array = []
current_index_on_one = 0
current_index_on_two = 0
current_merged_index = 0
for i in (0..merged_array_size - 1)
if array_one[current_index_on_one] < array_two[current_index_on_two]
merged_array[current_merged_index] = array_one[current_index_on_one]
current_index_on_one += 1
current_merged_index += 1
else
merged_array[current_merged_index] = array_two[current_index_on_two]
current_index_on_two += 1
current_merged_index += 1
end
end
return merged_array
end
我收到错误'未定义的方法`&lt;'为零:NilClass'。我不明白条件是如何收到这个。我调整了条件中的变量,它们给出了true或false值。我不确定是什么导致了这个错误。
答案 0 :(得分:4)
也许我错过了这一点,但你可以做到:
(array_one + array_two).sort
=> [1, 3, 4, 5, 7, 8]
答案 1 :(得分:2)
我收到错误&#39;未定义的方法`&lt;&#39;为零:NilClass&#39;。我不明白条件是如何收到的。
首先将索引0与索引0进行比较:
[3, 4, 8] [1, 5, 7]
0-----------0 #=> 3 < 1
然后将下限值的索引递增1:
[3, 4, 8] [1, 5, 7]
0--------------1 #=> 3 < 5
等等:
[3, 4, 8] [1, 5, 7]
1-----------1 #=> 4 < 5
[3, 4, 8] [1, 5, 7]
2--------1 #=> 8 < 5
[3, 4, 8] [1, 5, 7]
2-----------2 #=> 8 < 7
那时你得到:
[3, 4, 8] [1, 5, 7]
2--------------3 #=> 8 < nil
索引3超出了数组的范围,因此array_two[current_index_on_two]
返回nil
并且:
if array_one[current_index_on_one] < array_two[current_index_on_two]
# ...
end
变为
if 8 < nil
# ...
end
导致ArgumentError(comparison of Integer with nil failed)
。如果nil
在左侧,则您获得NoMethodError (undefined method `<' for nil:NilClass)
。
答案 2 :(得分:1)
这是您使用递归编写merge
的一种方法。请注意,如您所指定的,两个输入必须已经排序,否则输出将无效。输入的大小可能不同。
def merge (xs, ys)
if xs.empty?
ys
elsif ys.empty?
xs
else
x, *_xs = xs
y, *_ys = ys
if x < y
[x] + (merge _xs, ys)
else
[y] + (merge xs, _ys)
end
end
end
merge [ 1, 3, 4, 6, 8, 9 ], [ 0, 2, 5, 7 ]
# => [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
答案 3 :(得分:0)
假设您有两个已排序的数组。您需要使用递归创建管道来处理每个数组。检查每次迭代看
任一数组的索引 0
中的值较低,从数组中删除该数值并将该值附加到result
数组。
def merge_arrays(a, b)
# build a holder array that is the size of both input arrays O(n) space
result = []
# get lower head value
if a[0] < b[0]
result << a.shift
else
result << b.shift
end
# check to see if either array is empty
if a.length == 0
return result + b
elsif b.length == 0
return result + a
else
return result + merge_arrays(a, b)
end
end
> a = [3, 4, 6, 10, 11, 15]
> b = [1, 5, 8, 12, 14, 19]
> merge_arrays(a, b)
#=> [1, 3, 4, 5, 6, 8, 10, 11, 12, 14, 15, 19]
答案 4 :(得分:0)
我对您的代码进行了细微更改,以使其正常工作。请参阅内部的评论。
array_one = [2, 3, 4, 8, 10, 11, 12, 13, 15]
array_two = [1, 5, 6, 7, 9, 14]
def merge_arrays(array_one, array_two)
array_one, array_two = array_two, array_one if array_one.length > array_two.length # (1) swap arrays to make satement (3) work, need array_two always be the longest
merged_array_size = array_one.length + array_two.length
merged_array = []
current_index_on_one = 0
current_index_on_two = 0
current_merged_index = 0
for i in (0...merged_array_size-1) # (2) three points to avoid the error
if (!array_one[current_index_on_one].nil? && array_one[current_index_on_one] < array_two[current_index_on_two]) # (3) check also if array_one is nil
merged_array[current_merged_index] = array_one[current_index_on_one]
current_index_on_one += 1
current_merged_index += 1
else
merged_array[current_merged_index] = array_two[current_index_on_two]
current_index_on_two += 1
current_merged_index += 1
end
end
merged_array[current_merged_index] = array_one[current_index_on_one] || array_two[current_index_on_two] # (4) add the missing element at the end of the loop, looks what happen if you comment out this line
return merged_array
end
p merge_arrays(array_one, array_two)
# => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
错误即将发生,因为循环正在向前迈出一步。解决方案是先停止并在循环结束时插入缺少的元素。
它也适用于:
# for i in (1...merged_array_size)
# and
# for i in (1..merged_array_size-1)
# and
# (merged_array_size-1).times do
答案 5 :(得分:0)
arr1 = [3, 4, 8, 9, 12]
arr2 = [1, 5, 7, 8, 13]
arr = [arr1, arr2]
idx = [0, 0]
(arr1.size + arr2.size).times.with_object([]) do |_,a|
imin = [0, 1].min_by { |i| arr[i][idx[i]] || Float::INFINITY }
a << arr[imin][idx[imin]]
idx[imin] += 1
end
#=> [1, 3, 4, 5, 7, 8, 8, 9, 12, 13]