给定数组
[50,30,0,0,10,0,30,60,0]
我需要用计算值替换零来创建“曲线”,例如,在10到30之间,零可以用20代替。
我一直认为必须有一个很酷的红宝石方式来做这件事,但我找不到一个。有人可以帮忙吗?解决方案需要考虑多个相邻的零,并在范围的开始和结束处为零。
任何想法?
答案 0 :(得分:2)
您似乎不知道的术语是interpolation。维基百科的文章是一个很好的起点 - 究竟什么算法最适合你取决于你的问题的确切背景,所以我们不能在这里给你一个真正的答案。
答案 1 :(得分:1)
a =[50,30,0,0,10,0,30,60,0]
a.each_index{|i| a[i] = a[i-1] - ((a[i-2] - a[i-1])/2).to_i if a[i] == 0 && i > 1 }
puts a.inspect # [50, 30, 20, 15, 10, 8, 30, 60, 75]
我无法理解为什么最后一个数字可能在你的规格中是80?另外,它不适用于数组中的前两项。
答案 2 :(得分:1)
如果没有连续的零,这个难以理解的单线程就行了(list
是给定的数字列表):
[0, *list, 0].each_cons(3).map { |p, x, n| x == 0 ? (p + n)/2 : x }
我认为只有Ruby 1.9。
答案 3 :(得分:0)
def find_consecutive_values( array, value=nil )
raise "Need a value or block to find" unless value || block_given?
start = last = nil
ranges = []
indices = array.each_with_index do |o,i|
if ((block_given? && yield(o)) || o==value)
start = i unless start
last = i
else
ranges << (start..last) if start && last
start = last = nil
end
end
ranges << (start..last) if start && last
ranges
end
def interpolate_zeros( array, round=false )
result = array.dup
find_consecutive_values( array, 0 ).each do |range|
next unless range.first>0 && range.last<(array.length-1)
before = result[range.first - 1]
after = result[range.last + 1]
diff = after - before
size = (range.last - range.first + 2).to_f
range.each_with_index do |i,idx|
value = before + diff * (idx+1)/size
value = value.round if round
result[i] = value
end
end
result
end
p interpolate_zeros( [0,50,30,0,0,10,0,30,60,0], true )
#=> [0, 50, 30, 23, 17, 10, 20, 30, 60, 0]
答案 4 :(得分:0)
偶然发现了这个问题。有一个红宝石宝石“插补器”,它可以做你想要的,也可能更多:
http://interpolator.rubyforge.org。
这是一个简短的介绍:
http://fabianosoriani.wordpress.com/2010/02/23/ruby-interpolation-with-gem-interpolator/