0

我是 Ruby 新手,需要向我解释一段代码。要排序的数组是这个:

books = ["Charlie and the Chocolate Factory", "War and Peace", "Utopia", 
"A Brief History of Time", "A Wrinkle in Time"]

下面的代码块对这个数组booksAZ 进行排序

books.sort! { |firstBook, secondBook| firstBook <=> secondBook }

下面的代码块对这个数组booksZA 进行排序

books.sort! { |firstBook, secondBook| secondBook <=> firstBook }

为什么是这样?为什么第一个排序 AZ 而第二个排序 ZA?我有点理解组合比较运算符<=>。它根据比较返回 -1、1 或 0。但是这是如何排序的呢?谢谢!

4

2 回答 2

3

排序运算符的作用类似于:它告诉您某事物是否小于、大于或等于排序顺序中的另一个对象。所以你的第一个块问“是firstBook之前还是之后secondBook”,第二个块问“secondBook是之前还是之后first book”。如您所见,答案是相反的:

  • “A”“B”之前("A" <=> "B" == -1
  • “B”“A”之后("B" <=> "A" == 1

所以如果你颠倒问题的顺序,你会得到相反的答案,这意味着(比较类型)排序算法会给出相反的结果。

于 2018-07-06T00:20:00.793 回答
1

排序算法使用块的返回值,在这种情况下,它是比较运算符 ( <=>) 的结果。何时返回和-1的顺序将保持不变(即在之前取决于值,算法将保持当前的顺序并在其中知道是否应该在( ) 之前或之后 ( ) 进行排序,或者两者是否是等效()。abababab-110

该算法反复比较相邻的元素对,直到所有元素都有序为止。

让我们添加一些输出,看看当您对图书列表调用 sort 时会发生什么。这将使我们对 sort 方法的作用有所了解。我添加了注释来说明排序的每个步骤是如何改变书籍数组的。请注意,在这个例子中,讨论如何排序“交换”位置被简化了。

> books = ["Charlie and the Chocolate Factory", "War and Peace", "Utopia", "A Brief History of Time", "A Wrinkle in Time"]
> books.sort! do |a, b|
>   result = a <=> b
>   puts %(\n"#{ a }" <=> "#{ b }"  #=> #{ result })  # Print out which elements are being compared and the result
>   result
> end

"Charlie and the Chocolate Factory" <=> "War and Peace"  #=> -1
# ["Charlie and the Chocolate Factory", "War and Peace", "Utopia", "A Brief History of Time", "A Wrinkle in Time"]  *** No change

"War and Peace" <=> "Utopia"  #=> 1
# ["Charlie and the Chocolate Factory", "Utopia", "War and Peace", "A Brief History of Time", "A Wrinkle in Time"]  *** Positions of "Utopia" and "War and Peace" are swapped

"Charlie and the Chocolate Factory" <=> "Utopia"  #=> -1
# ["Charlie and the Chocolate Factory", "Utopia", "War and Peace", "A Brief History of Time", "A Wrinkle in Time"]  *** No change

"War and Peace" <=> "A Brief History of Time"  #=> 1
# ["Charlie and the Chocolate Factory", "Utopia", "A Brief History of Time", "War and Peace", "A Wrinkle in Time"]  *** Positions of "War and Peace" and "A Brief History of Time" are swapped

"Utopia" <=> "A Brief History of Time"  #=> 1
# ["Charlie and the Chocolate Factory", "A Brief History of Time", "Utopia", "War and Peace", "A Wrinkle in Time"]  *** Positions of "Utopia" and "A Brief History of Time" are swapped

"Charlie and the Chocolate Factory" <=> "A Brief History of Time"  #=> 1
# ["A Brief History of Time", "Charlie and the Chocolate Factory", "Utopia", "War and Peace", "A Wrinkle in Time"]  *** Positions of "Charlie and the Chocolate Factory" and "A Brief History of Time" are swapped

"War and Peace" <=> "A Wrinkle in Time"  #=> 1
# ["A Brief History of Time", "Charlie and the Chocolate Factory", "Utopia", "A Wrinkle in Time", "War and Peace"]  *** Positions of "War and Peace" and "A Wrinkle in Time" are swapped

"Utopia" <=> "A Wrinkle in Time"  #=> 1
# ["A Brief History of Time", "Charlie and the Chocolate Factory", "A Wrinkle in Time", "Utopia", "War and Peace"]  *** Positions of "Utopia" and "A Wrinkle in Time" are swapped

"Charlie and the Chocolate Factory" <=> "A Wrinkle in Time"  #=> 1
# ["A Brief History of Time", "A Wrinkle in Time", "Charlie and the Chocolate Factory", "Utopia", "War and Peace"]  *** Positions of "Charlie and the Chocolate Factory" and "A Wrinkle in Time" are swapped

"A Brief History of Time" <=> "A Wrinkle in Time"  #=> -1
# ["A Brief History of Time", "A Wrinkle in Time", "Charlie and the Chocolate Factory", "Utopia", "War and Peace"]  *** No change

# Done! All elements have been sorted, so the algorithm exits.

=> ["A Brief History of Time", "A Wrinkle in Time", "Charlie and the Chocolate Factory", "Utopia", "War and Peace"]

当比较从a <=> b变为 时b <=> a,结果被反转,这导致排序以相反的顺序进行。

> books = ["Charlie and the Chocolate Factory", "War and Peace", "Utopia", "A Brief History of Time", "A Wrinkle in Time"]
> books.sort! do |a, b|
>   result = b <=> a
>   puts %(\n"#{ b }" <=> "#{ a }"  #=> #{ result })  # Print out which elements are being compared and the result
>   result
> end

"A Wrinkle in Time" <=> "A Brief History of Time"  #=> 1

"Charlie and the Chocolate Factory" <=> "A Brief History of Time"  #=> 1

"Charlie and the Chocolate Factory" <=> "A Wrinkle in Time"  #=> 1

"Utopia" <=> "A Brief History of Time"  #=> 1

"Utopia" <=> "A Wrinkle in Time"  #=> 1

"Utopia" <=> "Charlie and the Chocolate Factory"  #=> 1

"War and Peace" <=> "A Brief History of Time"  #=> 1

"War and Peace" <=> "A Wrinkle in Time"  #=> 1

"War and Peace" <=> "Charlie and the Chocolate Factory"  #=> 1

"War and Peace" <=> "Utopia"  #=> 1
=> ["War and Peace", "Utopia", "Charlie and the Chocolate Factory", "A Wrinkle in Time", "A Brief History of Time"]

另请参阅Array#sort 的文档!

于 2018-07-06T01:00:20.367 回答