2

我尝试为Chris Pine 教程第 7 章编写自己的字母搜索,并且我想实现一个二进制方法。字符串输入没有有效性,所以我不知道整数与字符串混合会发生什么,但我的想法是只为字符串列表执行此操作。

#get list of strings
puts "type words to make a list. type 'exit' to leave program."
x = ()
list = []
while x.to_s.upcase != 'EXIT'
    x = gets.chomp
    list.push(x)
end 
list.pop

#binary method

nano = list.length
half= list.each_slice(nano/2).to_a
left = half[0]
right = half[1]

nanol=left.length
nanor=right.length

#initialize results array

A = []

for i in 0..nano-1
    smallest_left = left.min
    smallest_right = right.min

        #no difference with this commented out or not
    #if nanol==0
    #    A<<smallest_right
    #end
    #if nanor==0
    #    A<<smallest_left
    #end

        #error message points to the line below (rb:44)
    if smallest_left<smallest_right
        A << smallest_left
        print A
        left.pop[i]
    elsif smallest_left>smallest_right
        A << smallest_right
        print A
        right.pop[i]
    else
        print A
    end
end

对于 input = ['z','b','r','a'] 我可以看到列表在错误中排序:

["a"]["a", "b"]["a", "b", "r"] rb:44:in `<': comparison of String with nil failed (ArgumentError)

请帮我看看我的错误:)提前谢谢!

4

1 回答 1

1

发生异常是因为您尝试比较 nil。当 nil 在左侧时,您会得到不同的异常。

'1' < nil
#=> scratch.rb:1:in `<': comparison of String with nil failed (ArgumentError)

nil > '1'
scratch.rb:1:in `<main>': undefined method `>' for nil:NilClass (NoMethodError)

Your code gets into this situation when the left or right array is empty (ie all of its elements have been added to A already). Presumably, this is why you had originally added the if-statements for nanol == 0 and nanor == 0 (ie to handle when one of the arrays is empty).

Your if-statements have a couple of issues:

  1. You do need the nanol == 0 and nanor == 0 statements
  2. The three if-statements are always run, even though only one would apply in an iteration
  3. nanol and nanor are never re-calculated (ie they will never get to zero)
  4. When the left and right values are equal, you don't actually add anything to the A array

The inside of your iteration should be:

smallest_left = left.min
smallest_right = right.min

nanol=left.length
nanor=right.length  

if nanol == 0   #Handles left no longer having values
    A << right.delete_at(right.index(smallest_right) || right.length)
elsif nanor == 0    #Handles right no longer having values
    A << left.delete_at(left.index(smallest_left) || left.length)
elsif smallest_left < smallest_right
    A << left.delete_at(left.index(smallest_left) || left.length)
elsif smallest_left > smallest_right
    A << right.delete_at(right.index(smallest_right) || right.length)
else #They are equal so take one
    A << left.delete_at(left.index(smallest_left) || left.length)
end

You will still have an issue (no error, but unexpected results) when your list has an odd number of elements. But hopefully that answers your question.

于 2013-01-30T03:25:16.860 回答