我有两个未知长度的数组。一个元素需要均匀(尽可能均匀地)分布在另一个 中。
假设数组中的+元素是实际值的占位符的示例。我省略了数组逗号分隔符以消除视觉噪音并使模式更明显。
a = [++++++++++] # 10 element array with + characters representing array items
b = [] # empty array
a.interweave(b) #=> [++++++++++]
b = [1]
a.interweave(b) #=> [+++++1+++++]
b = (1..2).to_a
a.interweave(b) #=> [+++1+++2++++]
b = (1..3).to_a
a.interweave(b) #=> [++1++2+++3+++] # any remaining + are distributed to the end chunks.
b = (1..4).to_a
a.interweave(b) #=> [++1++2++3++4++]
b = (1..5).to_a
a.interweave(b) #=> [+1+2++3++4++5++]
b = (1..6).to_a
a.interweave(b) #=> [+1+2+3+4++5++6++]
b = (1..7).to_a
a.interweave(b) #=> [+1+2+3+4+5+6++7++]
b = (1..8).to_a
a.interweave(b) #=> [+1+2+3+4+5+6+7+8++]
b = (1..9).to_a
a.interweave(b) #=> [+1+2+3+4+5+6+7+8+9+]
b = (1..10).to_a
a.interweave(b) #=> [+1+2+3+4+5+6+7+8+9+10]
b = (1..11).to_a
a.interweave(b) #=> [+,1,+,2,+,3,+,4,+,5,+,6,+,7,+,8,+,9,+,10,11] # the remaining elements from b are added to the end
我正在寻找Ruby中的高性能算法。
答案 0 :(得分:2)
class Array
def interweave(a2)
a1 = self.dup
arrays = [a1, a2].sort_by {|a| a.length}.reverse
offset, remainder = arrays[0].length.divmod(arrays[1].length + 1)
prev_jump = 0
arrays[1].reverse.each_with_index do |e, i|
remainder > 0 ? (adjust = 1; remainder -= 1) : adjust = 0
jump = offset + adjust + 1
arrays[0].insert( -(prev_jump + jump), e)
prev_jump += jump
end
arrays[0]
end
end
a1 = [0,0,0,0,0,0,0,0,0,0]
p a1.interweave [1] # => [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]
p a1.interweave (1..2).to_a # => [0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0]
p a1.interweave (1..3).to_a # => [0, 0, 1, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0]
p a1.interweave (1..4).to_a # => [0, 0, 1, 0, 0, 2, 0, 0, 3, 0, 0, 4, 0, 0]
p a1.interweave (1..5).to_a # => [0, 1, 0, 2, 0, 0, 3, 0, 0, 4, 0, 0, 5, 0, 0]
p a1.interweave (1..6).to_a # => [0, 1, 0, 2, 0, 3, 0, 4, 0, 0, 5, 0, 0, 6, 0, 0]
p a1.interweave (1..7).to_a # => [0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 0, 7, 0, 0]
p a1.interweave (1..8).to_a # => [0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8, 0, 0]
p a1.interweave (1..9).to_a # => [0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8, 0, 9, 0]
p a1.interweave (1..10).to_a # => [0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8, 0, 9, 0, 10]
p a1.interweave (1..11).to_a # => [1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8, 0, 9, 0, 10, 0, 11]
p a1.interweave (1..12).to_a # => [1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8, 0, 9, 0, 10, 0, 11, 12]
我做到这一点,所以最短的阵列交织成最长的阵列,然后才注意到你想要在最后添加剩余的剩余物。现在太累了,但你可以根据需要进行调整。
答案 1 :(得分:2)
另一种方式:
def weave(xx,yy)
x = xx.dup
y = yy.dup
n_extra = [y.size - x.size + 1, 0].max
y_extra = y.slice!(y.size - n_extra, n_extra)
z = x.class.new
loop do
z += (x.slice!(0,((x.size)/(y.size+1.0)).floor) + y.slice!(0,1))
break if y.empty?
end
z + x + y_extra
end
x = ('-'*10).chars
# => ["-", "-", "-", "-", "-", "-", "-", "-", "-", "-"]
p weave(x, ['a', 'b', 'c'])
# => ["-", "-", "a", "-", "-", "b", "-", "-", "-", "c", "-", "-", "-"]
p weave(x, ['a', 'b', 'c']).join # => "--a--b---c---"
p weave('----------', 'abc') # => "--a--b---c---"
y = (1..12).each_with_object([]) {|i,a| a << ('a'..'z').to_a.first(i)}
y.each {|e| p weave(x, e).join}
"-----a-----"
"---a---b----"
"--a--b---c---"
"--a--b--c--d--"
"-a-b--c--d--e--"
"-a-b-c-d--e--f--"
"-a-b-c-d-e-f--g--"
"-a-b-c-d-e-f-g-h--"
"-a-b-c-d-e-f-g-h-i-"
"-a-b-c-d-e-f-g-h-i-j"
"-a-b-c-d-e-f-g-h-i-jk"
"-a-b-c-d-e-f-g-h-i-jkl"
编辑:我对原始解决方案进行了一些更改:
weave
的前两行,因此参数不会被更改。.join
的末尾删除了(arr + x + y_extra)
。z = []
更改为z = x.class.new
,以允许weave
的参数为数组或字符串。关于((x.size)/(y.size+1.0)).floor
的一句话。假设x = ['-','-','-','-','-','-'] and y = ['a', 'b', 'c']
。然后:
z => ['-', 'a']
,x => ['-','-','-','-','-']
和y => ['b', 'c']
。x
的元素,则y.size+1.0 => 3.0
的剩余部分将被划分为x.size/3.0 => 5/3.0 => 1.67
个时间间隔,每个时间间隔都包含x
个元素。由于它们无法分割,而较大的群组位于右侧,我们会从1.67.floor => 1
中剥离x
元素,将y
的下一个元素追加到{{} 1}},然后重复,直到z
。