Arrays 交换数组中未排序的前两个元素

Arrays 交换数组中未排序的前两个元素,arrays,ruby,Arrays,Ruby,我试图编写代码,查找数组中无序的前两个元素并交换它们。我写了这段代码,但当我运行它的时候,我只打印了3个。有人能帮我重写代码让它工作吗 arr = [5, 22, 29, 39, 19, 51, 78, 96, 84] i = 0 while (i < arr.size - 1 and arr[i] < arr[i + 1]) i = i + 1 end puts i arr[i] = arr[i + 1] arr[i + 1] = arr[i] 您可以编写以下内容: arr

我试图编写代码,查找数组中无序的前两个元素并交换它们。我写了这段代码,但当我运行它的时候,我只打印了3个。有人能帮我重写代码让它工作吗

arr = [5, 22, 29, 39, 19, 51, 78, 96, 84]
i = 0
while (i < arr.size - 1 and arr[i] < arr[i + 1])
  i = i + 1
end
puts i
arr[i] = arr[i + 1]
arr[i + 1] = arr[i]

您可以编写以下内容:

arr = [5, 22, 29, 39, 19, 51, 78, 96, 84]
arr = [5, 22, 29, 39, 19, 51, 78, 96, 84]
您可以使用耦合来获取对及其索引*。 然后,按相反的顺序修改对的第一个索引,修改插入交换对的原始数组:

arr = [1,2,3,5,4]

arr.each_cons(2).with_index.find { |(a, b), i| a > b }
   .then { |e, i| arr[i..i+1] = e.reverse if i }

arr
#=> [1, 2, 3, 4, 5]
*工作原理:

arr.each_cons(2).with_index.to_a
#=> [[[1, 2], 0], [[2, 3], 1], [[3, 5], 2], [[5, 4], 3]]

注意:用于较旧的Ruby而不是Objectthen

当前代码的问题是:

arr[i] = arr[i + 1]
arr[i + 1] = arr[i]
其中,您将arr[i]设置为等于arr[i+1],然后使用设置为arr[i+1]的arr[i]重新绘制arr[i+1]的内容。这将两个元素都设置为arr[i+1]的内容。您可以使用临时变量来保存arr[i]的上一个值

一种更干净的方法是使用

这样就不需要临时变量

从和的答案中获得一些灵感。下面是另一种查找索引和交换值的重构方法


元素交换有问题,因为arr[i+1]=arr[i]=arr[i+1],所以arr[i+1]没有改变。您需要使用一个临时变量,或者更好地使用并行赋值,正如我在回答中所做的那样。此外,如果arr完全按顺序开始,当i=arr.size-1时,您将引发一个异常,因为您将比较最后一个元素arr[i]和arr[arr.size],后者为零。我可以问您一个问题来检查我的解释是否正确吗。每个_cons2方法用于找出无序的前两个元素。find_index用于查找这两个元素的索引。arr[1,2]。如果i-它是如何工作的,则反转?我知道如果第一个元素更大,它交换位置-较大的元素39替换为较小的元素值19。我的理解正确吗?谢谢@《疯狂代码忍者》每个_cons2将集合从[1,2,4,3]转换为[[1,2]、[2,4]、[4,3]]。然后我使用find|u index{a,b|a>b}来查找元素无序的索引。在[[1,2]、[2,4]、[4,3]]的情况下,它将返回2,因为[4,3]与{a,b | a>b}标准匹配。如果找到匹配项,我将被设置,如果没有找到匹配项,我将为零,所以如果我确保找到匹配项,我们只交换元素。arr[i,2]创建一个新数组,从i开始,取2个元素。您用相反的版本替换了阵列的这一部分。谢谢@3limin4t0r!现在拿2对我来说很有意义。谢谢
tmp = arr[i]
arr[i] = arr[i + 1]
arr[i + 1] = tmp
arr[i], arr[i + 1] = arr[i + 1], arr[i]
arr = [5, 22, 29, 39, 19, 51, 78, 96, 84]
i = arr.each_cons(2).find_index { |a, b| a > b }
arr[i, 2] = arr[i, 2].reverse if i

arr #=> [5, 22, 29, 19, 39, 51, 78, 96, 84]