我正在关注Coursera课程,我正在尝试在Ruby中实现quicksort算法。我对语言和OOP的概念都很陌生。
我创建了两个函数:一个是quickSort函数,它调用分区例程(根据作为数组第一个元素的pivot将数组拆分为两个子数组)。
最终我将把这两个方法放在一个类Array下,但是现在我认为这样就行了。
我尝试在一个数组上运行它(a = [5,4,3,2,1]),但是我遇到了以下错误:
A2.rb:16:in `partition': undefined method `<' for true:TrueClass (NoMethodError)
from A2.rb:15:in `each'
from A2.rb:15:in `partition'
from A2.rb:33:in `quickSort'
这是我的代码:
def partition(array, left_idx, right_idx)
num_comp = array.length - 1
p = array[left_idx]
i = left_idx + 1
j = left_idx + 1
puts "#{left_idx}, #{right_idx}, #{array[j]} #{j}"
puts "pivot = #{p}"
for j in (left_idx + 1..right_idx)
if (left_idx < j < right_idx and left_idx < i < right_idx)
if (array[j] > p)
j = j + 1
else
array[i], array[j] = array[j], array[i]
i = i + 1
j = j + 1
end
end
end
#swap pivot and rightmost value in subarray that contains < p
array[1], array[i] = array[i], array[1]
pivot_idx = i
return array, num_comp, pivot_idx
end
def quickSort(array, start_idx, end_idx)
array_n, num_comp, pivot_idx = partition(array, start_idx, end_idx)
left_array = array_n[start_idx..pivot_idx - 1]
right_array = array_n[pivot_idx + 1..end_idx]
if (left_array.length > 1)
array_n = quickSort(array_n, start_idx, pivot_idx - 1)
end
if (right_array.length > 1)
array_n = quickSort(array_n, pivot_idx + 1, end_idx)
end
return array
end
#a = Array.new()
a = [5, 4, 3, 2, 1]
quickSort(a, 0, 4)
print "Array"
puts a
由于
答案 0 :(得分:4)
left_idx < j < right_idx
你不能这样做。
left_idx&lt; j首先解析为“True”
然后表达式变为真&lt; right_idx和&lt;是一个无效的运算符..
将expresison更改为if left_idx&lt; j&amp;&amp; j&lt; right_idx
答案 1 :(得分:2)
你不能这样做:
left_idx < j < right_idx and left_idx < i < right_idx
你需要建立条件:
((j > left_idx) && (j < left_idx)) && (etc)
答案 2 :(得分:0)
问题在于这一行:
if (left_idx < j < right_idx and left_idx < i < right_idx)
这是有效的数学,但是无效的Ruby(在大多数其他编程语言中也是无效的)。你想要的是:
if (left_idx < j and j < right_idx and left_idx < i and i < right_idx)
正在发生的是Ruby解释“&lt;”作为一种方法。因此,原始行变为:
if ((left_idx.<(j)).<(right_idx)) and ((left_idx.<(i)).<(right_idx))
在您的情况下,(left_idx。&lt;(j))的结果为“true”。所以它然后尝试调用&lt;在“真正的”类中,它不存在,导致你得到的错误。
答案 3 :(得分:0)
问题在于这一行:
(left_idx < j < right_idx and left_idx < i < right_idx)
left < middle < right
可能是人们通常用数学写的东西,但在Ruby中,<
并不特别 - 它只是一种方法。具体来说,返回布尔值的方法。 left_idx < j
的结果始终为true或false,然后您尝试将right_idx
与该值进行比较。显然,这没有任何意义。
您可以将该行写为
left_idx < j && j < right_idx #...
或
(left_idx..right_idx).include? j && (left_idx..right_idx).include? i
或
([i,j].all? {|v| (left_idx..right_idx).include? v})
编写quicksort的一种更惯用的方法是
def quicksort(arr)
pivot, *rest = arr
left,right = rest.partition{|v| v<pivot}.map{|a| if !a.empty? then quicksort(a) else a end}
left.push(pivot) + right
end
这可能仍然可以做得更好。请注意,这不是就地快速排序,但你的似乎也不是。