Ruby 在排序前后为具有重复元素的数组编制索引
这是一个基本问题:我有一个整数数组,其中可能包含重复的元素。我需要知道每个元素的索引,但是当我对数组进行排序时,每当我从新数组中选择一个元素时,我都希望能够从原始数组中引用相同的元素 我正在寻找一个解决问题的方法,或者是我正在采取的方法的解决方案 这是一个数组Ruby 在排序前后为具有重复元素的数组编制索引,ruby,algorithm,Ruby,Algorithm,这是一个基本问题:我有一个整数数组,其中可能包含重复的元素。我需要知道每个元素的索引,但是当我对数组进行排序时,每当我从新数组中选择一个元素时,我都希望能够从原始数组中引用相同的元素 我正在寻找一个解决问题的方法,或者是我正在采取的方法的解决方案 这是一个数组 a = [1, 2, 3, 4, 3, 5, 2] 有两个2和两个3,但是如果我使用第一个2(从左起),我想使用索引1,如果我使用第二个2,我想使用索引6。因此,我使用一个助手数组来执行以下操作: helper = [0, 1, 2,
a = [1, 2, 3, 4, 3, 5, 2]
有两个2和两个3,但是如果我使用第一个2
(从左起),我想使用索引1,如果我使用第二个2
,我想使用索引6。因此,我使用一个助手数组来执行以下操作:
helper = [0, 1, 2, 3, 4, 5, 6]
我将迭代并使用它访问a
中的每个元素我可以用
每个带有索引的\u来完成这项工作,但问题是在我对数组排序时开始的
现在我有一个排序顺序
sort_order = [2, 4, 1, 5, 3]
我使用sort\u by
根据排序顺序对a
进行排序,以生成
sorted_a = [2, 2, 4, 1, 5, 3, 3]
您可以假设输入中的所有元素都以sort\u顺序存在
,以避免sort\u by
异常
现在的问题是,我的helper
数组应该更新以匹配新位置。每个元素的排序方式应与a
的排序方式相同,因为不清楚新数组中的前2个元素是位于原始数组的索引1还是索引6
所以我的新助手数组可能看起来像
new_helper = [1, 6, 3, 0, 5, 2, 4]
因此,如果采用这种方法,在给定原始数组和排序顺序的情况下,如何生成新的\u helper
数组
也许有更好的方法可以做到这一点?我建议首先使用helper数组压缩原始数组,根据来自原始数组的组件对压缩后的数组进行排序,然后解压缩它们(不幸的是,此方法不存在,但您可以进行转置)。或者,您可以实现Hunter指出的自己的排序逻辑。我建议首先使用helper数组压缩原始数组,根据来自原始数组的组件对压缩后的数组进行排序,然后解压缩它们(不幸的是,此方法不存在,但您可以进行转置)。或者,您可以实现Hunter指出的自己的排序逻辑。在交换主数组时,需要交换helper数组中的值
loop do
swapped = false
0.upto(list.size-2) do |i|
if list[i] > list[i+1]
list[i], list[i+1] = list[i+1], list[i] # swap values
helper[i], helper[i+1] = helper[i+1], helper[i]; #swap helper values
swapped = true
end
end
break unless swapped
end
示例
irb(main):001:0> def parallel_sort(list, helper)
irb(main):002:1> loop do
irb(main):003:2* swapped = false
irb(main):004:2> 0.upto(list.size-2) do |i|
irb(main):005:3* if list[i] > list[i+1]
irb(main):006:4> list[i], list[i+1] = list[i+1], list[i] # swap values
irb(main):007:4> helper[i], helper[i+1] = helper[i+1], helper[i]; #swap helper values
irb(main):008:4* swapped = true
irb(main):009:4> end
irb(main):010:3> end
irb(main):011:2> break unless swapped
irb(main):012:2> end
irb(main):013:1> return [list, helper]
irb(main):014:1> end
=> nil
irb(main):015:0> a = [3,2,1]
=> [3, 2, 1]
irb(main):016:0> b = ["three","two","one"]
=> ["three", "two", "one"]
irb(main):017:0> parallel_sort(a,b)
=> [[1, 2, 3], ["one", "two", "three"]]
irb(main):018:0>
交换主数组时,需要交换辅助数组中的值
loop do
swapped = false
0.upto(list.size-2) do |i|
if list[i] > list[i+1]
list[i], list[i+1] = list[i+1], list[i] # swap values
helper[i], helper[i+1] = helper[i+1], helper[i]; #swap helper values
swapped = true
end
end
break unless swapped
end
示例
irb(main):001:0> def parallel_sort(list, helper)
irb(main):002:1> loop do
irb(main):003:2* swapped = false
irb(main):004:2> 0.upto(list.size-2) do |i|
irb(main):005:3* if list[i] > list[i+1]
irb(main):006:4> list[i], list[i+1] = list[i+1], list[i] # swap values
irb(main):007:4> helper[i], helper[i+1] = helper[i+1], helper[i]; #swap helper values
irb(main):008:4* swapped = true
irb(main):009:4> end
irb(main):010:3> end
irb(main):011:2> break unless swapped
irb(main):012:2> end
irb(main):013:1> return [list, helper]
irb(main):014:1> end
=> nil
irb(main):015:0> a = [3,2,1]
=> [3, 2, 1]
irb(main):016:0> b = ["three","two","one"]
=> ["three", "two", "one"]
irb(main):017:0> parallel_sort(a,b)
=> [[1, 2, 3], ["one", "two", "three"]]
irb(main):018:0>
在循环内排序很少是个好主意。。。。如果您正在这样做,那么使用treap(平均速度很快,但很少有操作需要一段时间)或红黑树(速度相对较慢,但操作时间相当一致)可能会更好。它们非常类似于哈希表,只是速度不快,并且使用树将元素按顺序存储
无论如何,为什么不使用一个既保存排序依据的值又保存辅助值的类呢?然后它们总是在一起,您不需要自定义排序算法。在循环内排序很少是个好主意。。。。如果您正在这样做,那么使用treap(平均速度很快,但很少有操作需要一段时间)或红黑树(速度相对较慢,但操作时间相当一致)可能会更好。它们非常类似于哈希表,只是速度不快,并且使用树将元素按顺序存储
无论如何,为什么不使用一个既保存排序依据的值又保存辅助值的类呢?然后它们总是在一起,您不需要自定义排序算法。列出原始数据对和该数据的索引。像这样:
a = [(1, 0), (2, 1), (3, 2), (4, 3), (3, 4), (5, 5), (2,6)]
对该列表进行排序(按字典顺序排列,或者忽略该列表的第二部分,除非将其随身携带)。每对中的第二项告诉您元素在原始数组中的位置。列出原始数据对和该数据的索引。像这样:
a = [(1, 0), (2, 1), (3, 2), (4, 3), (3, 4), (5, 5), (2,6)]
对该列表进行排序(按字典顺序排列,或者忽略该列表的第二部分,除非将其随身携带)。每对中的第二项告诉您元素在原始数组中的位置。因为您有排序顺序,所以您的数组已经排序了,所以我们应该利用这一事实作为优势。我提出了一个简单的解决方案:
a = [1, 2, 3, 4, 3, 5, 2]
sort_order = [2, 4, 1, 5, 3]
# Save indices
indices = Hash.new { |hash, key| hash[key] = [] }
a.each_with_index { |elem, index| indices[elem] << index }
# Sort the array by placing elements into "right" positions
sorted = []
helper = []
sort_order.each do |elem|
indices[elem].each do |index|
sorted << elem
helper << index
end
end
p sorted
p helper
a=[1,2,3,4,3,5,2]
排序顺序=[2,4,1,5,3]
#保存索引
index=Hash.new{| Hash,key | Hash[key]=[]}
a、 每个带有_index{| elem,index | index[elem]的"u |由于您有
排序顺序
,您的数组已经排序了,因此我们应该利用这一事实作为优势。我提出了一个简单的解决方案:
a = [1, 2, 3, 4, 3, 5, 2]
sort_order = [2, 4, 1, 5, 3]
# Save indices
indices = Hash.new { |hash, key| hash[key] = [] }
a.each_with_index { |elem, index| indices[elem] << index }
# Sort the array by placing elements into "right" positions
sorted = []
helper = []
sort_order.each do |elem|
indices[elem].each do |index|
sorted << elem
helper << index
end
end
p sorted
p helper
a=[1,2,3,4,3,5,2]
排序顺序=[2,4,1,5,3]
#保存索引
index=Hash.new{| Hash,key | Hash[key]=[]}
a、 每个带有_index{| elem,index | index[elem]的|只要元素的值相同,辅助数组是否指向与原始数组不同的元素有关系?这些值并不重要(在我使用它们的方法的上下文中),但位置是。这是我在创建助手数组时想到的,因此新的助手数组应该指向同一个元素。然后,您需要自己实现排序逻辑,并且每当您交换数组中的位置时,也会在助手数组中交换位置。助手数组是否指向不同的元素f有关系吗只要该元素的值相同,就可以使用原始rom?这些值并不重要(在使用它们的方法的上下文中),但位置是。这是我在创建助手数组时想到的,因此新的助手数组应该指向同一个元素。然后,您需要自己实现排序逻辑,并且每当您交换数组中的位置时,也会将其交换到助手数组中。尽管排序顺序基于自定义排序顺序数组,