所有可能总和的最小值,最大值,平均值和中值(Ruby)

时间:2018-03-01 16:10:07

标签: ruby algorithm recursion average minimum

我一直在使用我发现here的一段Ruby代码。

以下是代码:

a = [1, 4, 7, 13]

def add(ary, idx, sum)
    (idx...ary.length).each do |i|
        add(ary, i+1, sum + ary[i])
    end
    puts sum
end
add(a, 0, 0)

事情是,我不需要它吐出添加所有总和的结果。我需要总和的最小值,最大值,中位数和平均值。

如何修改此代码才能获取它们?我是Ruby的初学者。我一直在使用此代码,然后将结果传输到Excel以获取我想要的值。但感觉我的方法可能更有效率。

感谢您的帮助。

编辑:预期结果 - 目前代码在我的屏幕上吐出:

25
12
18
5
21
8
14
1
24
11
17
4
20
7
13
0

我希望它吐出最小值,平均值,中位数和最大值:

0
12.5
12.5
25

4 个答案:

答案 0 :(得分:1)

a = [1, 4, 7, 13]

def all_sums(array)
    combination_lengths = (0..array.length)
    all_combinations = combination_lengths.flat_map do |c|
      array.combination(c).to_a
    end
    all_combinations.map(&:sum)
end

def print_min_max_avg_med(array)
  puts array.min
  puts array.max
  puts array.sum.to_f / array.length
  sorted_arr = array.sort
  puts sorted_arr[(array.length - 1) / 2] + sorted_arr[array.length / 2] / 2.0
end

print_min_max_avg_med(all_sums(a))

答案 1 :(得分:0)

好的,我们可以将它们存储在一个arrary中,而不是输出值,而是使用该数组来获取所需的值。 (由Stefan Pochmann咀嚼后编辑)

 a = [1, 4, 7, 13]

def add(ary, idx, sum, results = nil)
  unless results
    results = []
    first_run = true
  end
  (idx...ary.length).each do |i|
      add(ary, i+1, sum + ary[i], results)
  end
  results << sum

  if first_run
    puts results.min
    puts results.inject(&:+).to_f / results.size
    puts (results.sort[((results.size - 1) / 2)] + results.sort[(results.size / 2)]) / 2.0
    puts results.max
  end
end
add(a, 0, 0)

答案 2 :(得分:0)

好的,在看了Pochmann和Bronca的例子之后,我在谷歌搜索之后把它放在一起以获得更好的中位数。

a = [1, 4, 7, 13]

def all_sums(array)
    combination_lengths = (0..array.length)
    all_combinations = combination_lengths.flat_map do |c|
      array.combination(c).to_a
    end
    all_combinations.map(&:sum)
end

def median(array)
  sorted = array.sort
  len = sorted.length
  (sorted[(len - 1) / 2] + sorted[len / 2]) / 2.0
end

def print_min_max_avg_med(array)
  puts array.min
  puts array.empty? ? 0 : array.sum.to_f / array.length
  puts median(array)
  puts array.max
end

print_min_max_avg_med(all_sums(a))

我已经运行了一些测试,它似乎适用于奇数和偶数数组。希望这对未来其他人坚持我现在的位置是有用的。

感谢所有帮助过的人。

答案 3 :(得分:0)

最小和最大

最小和最大很容易。

def min_and_max_of_sums a
  return [nil, nil] if a.empty?      
  negs, nonnegs = a.partition { |n| n < 0 }
  [negs.any? ? negs.sum : nonnegs.min, nonnegs.any? ? nonnegs.sum : negs.max]
end

min_and_max_of_sums [1, 4, -5, 7, -8, 13]
  #=> [-13, 25]
min_and_max_of_sums [1, 2, 3]
  #=> [1, 6]
min_and_max_of_sums [-1, -2, -3]
  #=> [-6, -1]
min_and_max_of_sums []
  #=> [nil, nil]

<强>平均数

现在考虑平均值的计算。

如果 n 是数组 a 的大小,则 2 n 的元素组合< em> a 包含 0 n 元素之间。 1 此外,每个元素之间都有1-1的映射组合和 n - 0和1的向量,其中 n -vector的 ith 元素等于 1 当且仅当元素 a i 包含在组合中时。请注意 2 n 这样的 n -vectors,其中一半在中包含 1 ith 的位置。这意味着一半的组合包含元素 a i 。由于 i 是任意的,因此 a 的每个元素都出现在组合的一半中。

所有组合的所有元素之和的平均值等于 T / 2 n ,其中 T 是总和的总和每个组合的元素。每个元素 a i 出现在 2 n / 2 组合中,因此它对 T的贡献 equals(用Ruby术语表示)

a[i] * 2**(n)/2

由于这对 a 的每个元素都有效,所以平均值等于

a.sum * (2**(n)/2)/2**(n)
  => a.sum/2

这是一个例子。对于数组

a = [1, 4, 8]

总和的平均值是

a.sum/2
  #=> 13/2 => 6.5

如果我们按照定义计算平均值,我们将执行以下计算(当然得到相同的返回值)。

(0 + (1) + (4) + (8) + (1+4) + (1+8) + (4+8) + (1=4+8))/2**3
  #=> (4*1 + 4*4 + 4*8)/8
  #=> (1 + 4 + 8)/2
  #=> 6.5

我会将中位数的计算留给其他人。

1搜索“二项式系数之和”here