这是基本问题:我有一个可能重复元素的整数数组。我需要知道每个元素的索引,但是当我对数组进行排序时,每当我从新数组中选择一个元素时,我希望能够从原始数组中引用相同的元素。
我正在寻找问题的解决方案,或者可能是我正在采取的方法的解决方案。
这是一个数组
a = [1, 2, 3, 4, 3, 5, 2]
有两个2和两个3,但如果我正在使用第一个2
(从左侧),我想使用索引1,如果我正在使用第二个{{ 1}},我想使用索引6.所以我使用一个帮助器数组来允许我这样做:
2
我将迭代并用来访问helper = [0, 1, 2, 3, 4, 5, 6]
中的每个元素
我可以使用a
完成此操作,但问题在我对数组进行排序时开始。
现在我有一个排序顺序
each_with_index
我使用sort_order = [2, 4, 1, 5, 3]
根据sort_order对sort_by
进行排序,以生成
a
您可以假设输入中的所有元素都存在于sorted_a = [2, 2, 4, 1, 5, 3, 3]
中,以避免sort_order
例外。
现在的问题是我的sort_by
数组应该更新以匹配新的位置。每个元素的排序方式应与排除helper
的方式相同,因为不清楚新数组中的前2个是在索引1还是在原始数组的索引6处。
所以我的新助手数组可能看起来像
a
因此,如果我采用这种方法,在给定原始数组和排序顺序的情况下,如何生成new_helper = [1, 6, 3, 0, 5, 2, 4]
数组?
也许有更好的方法可以做到这一点?
答案 0 :(得分:1)
我建议首先使用辅助数组压缩原始数组,根据来自原始数组的组件对压缩数组进行排序,然后解压缩它们(不幸的是,这种方法不存在,但你可以进行转置)。或者你可以按照Hunter的指示实现你自己的排序逻辑。
答案 1 :(得分: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>
答案 2 :(得分:0)
在循环内进行排序很少是一个好主意....如果你这样做,你可能会更好地使用treap(平均快速但很少操作需要一段时间)或红黑树(相对较差)慢,但给出相当一致的操作时间)。这些非常类似于哈希表,除了它们不那么快,并且它们使用树保持元素按顺序存储。
无论哪种方式,为什么不使用保存值排序依据的类和辅助值?然后他们总是在一起,你不需要自定义排序算法。
答案 3 :(得分:0)
列出原始数据和数据索引的对。像这样:
a = [(1, 0), (2, 1), (3, 2), (4, 3), (3, 4), (5, 5), (2,6)]
对该列表进行排序(按字典顺序排列,或者只是忽略该对的第二部分除了随身携带)。每对中的第二项都会告诉您元素在原始数组中的位置。
答案 4 :(得分:0)
由于你有sort_order
,你的数组已经排序了,所以我们应该利用这个事实作为优势。我提出了这个简单的解决方案:
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
该算法基于Counting sort的思想,我稍微修改它以保存索引。