简体   繁体   中英

noMethodError on a < symbol ruby

enter image description here

The link for the error is above; I keep getting a noMethodError for a symbol and I am very confused

numList = [4,3,78,2,0,2]

def bubbleSort(list)
  again = true

  while again
    copy = list
    i = 0
    until i == list.length do
      list.each_with_index do |num, index|
        if list[index+1] < num 
          tempNum = list[index+1]
          list[index+1] = num
          list[index] = tempNum
        end
      end
      i = i+1
    end

    if copy != list
      again = true
    else
      again = false
    end
    p copy
  end
end

bubbleSort(numList)

As noted in comments, you are iterating with an index:

 list.each_with_index do |num, index|

But this includes the last index, which you're trying to access one past.

 if list[index+1] < num

list[index+1] return nil , which will give the error you're seeing.

irb(main):083:0> nil < 42
Traceback (most recent call last):
        5: from C:/Ruby26-x64/bin/irb.cmd:31:in `<main>'
        4: from C:/Ruby26-x64/bin/irb.cmd:31:in `load'
        3: from C:/Ruby26-x64/lib/ruby/gems/2.6.0/gems/irb-1.0.0/exe/irb:11:in `<top (required)>'
        2: from (irb):83
        1: from (irb):83:in `rescue in irb_binding'
NoMethodError (undefined method `<' for nil:NilClass)

It'd be important to avoid this access. I would also suggest avoiding the again boolean flag. Rather use loop and break out of the loop at the appropriate time.

def bubbleSort(list)
  loop do
    copy = list
    i = 0
    until i == list.length  
      list.each_with_index do |num, index|
        next if index == list.length - 1
      
        if list[index+1] < num 
          tempNum = list[index+1]
          list[index+1] = num
          list[index] = tempNum
        end
      end
      i = i+1
    end

    break if copy == list
    
    p copy
  end
end

Taking a step back and looking at how bubble sort works though, your implementation can be improved.

Each cycle through the array a bubble sort will advance the largest element to the end of the array. You don't need to cycle over the whole array each times, but can decrease the inner loop by one iteration each time.

You can also track the number of swaps. If no swaps are performed, the array is clearly sorted already, and the outer loop can be exited.

+---+---+---+---+
| 4 | 2 | 3 | 1 |  (starting state for loop)
+---+---+---+---+

  >---<
+---+---+---+---+
| 2 | 4 | 3 | 1 | (swap 4 and 2)
+---+---+---+---+

      >---<
+---+---+---+---+
| 2 | 3 | 4 | 1 | (swap 4 and 3)
+---+---+---+---+

          >---<
+---+---+---+---+
| 2 | 3 | 1 | 4 | (swap 4 and 1)
+---+---+---+---+

Three swaps are performed. The last position in the array is sorted.

+---+---+---+---+
| 2 | 3 | 1 | 4 | (starting state for loop)
+---+---+---+---+

      >---<
+---+---+---+---+
| 2 | 1 | 3 | 4 | (swap 3 and 1)
+---+---+---+---+

+---+---+---+---+
| 2 | 1 | 3 | 4 | (no swap needed for 1 and 3)
+---+---+---+---+

One swap is performed. Now the last two positions are sorted.

+---+---+---+---+
| 2 | 1 | 3 | 4 | (starting state for loop)
+---+---+---+---+

  >---<
+---+---+---+---+
| 1 | 2 | 3 | 4 | (swap 2 and 1)
+---+---+---+---+

One swap is performed. We know the last three positions are sorted. The first position therefore is sorted.

If the array is already sorted and we keep track of swaps:

+---+---+---+---+
| 1 | 2 | 3 | 4 | (starting state for loop)
+---+---+---+---+

+---+---+---+---+
| 1 | 2 | 3 | 4 | (no swap needed for 1 and 2)
+---+---+---+---+

+---+---+---+---+
| 1 | 2 | 3 | 4 | (no swap needed for 2 and 3)
+---+---+---+---+

+---+---+---+---+
| 1 | 2 | 3 | 4 | (no swap needed for 3 and 4)
+---+---+---+---+

Since zero swaps are performed, the array is known to be sorted. While bubble sort is worst case O(n^2), this technique can make it best case O(n).

def bubble_sort(arr)
  (arr.length-1).times do |x|
    swaps = 0

    0.upto(arr.length-x-2) do |i|
      if arr[i] > arr[i+1]
        temp = arr[i+1]
        arr[i+1] = arr[i]
        arr[i] = temp
        swaps += 1
      end
    end

    break if swaps == 0
  end
  
  arr
end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM