首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >对数组进行量化,以便量化值的子集仍然是一致量化的。

对数组进行量化,以便量化值的子集仍然是一致量化的。
EN

Stack Overflow用户
提问于 2015-04-03 00:29:23
回答 1查看 500关注 0票数 1

给定一个int的数组,我希望量化每个值,以便量化的值之和为100。每个量化的值也应该是一个整数。当整个数组被量化时,这是可行的,但是当一个量化值的子集被加起来时,它就不会与其余的值保持量化。

例如,44、40、7、2、0、0被量化为47、43、8、2、0、0(之和为100)。如果取最后4个量化值,其和为53,与第一个值一致(即47 + 53 = 100)。

但是对于值78,7,7,1,0,0,0,最后4个量化值(8,8,1,0,0)之和为17。第一个量化值为84,当加到17时不等于100。显然,这是由于四舍五入造成的。有没有办法调整四舍五入,使子集仍然是一致的?

下面是Ruby代码:

代码语言:javascript
复制
class Quantize
  def initialize(array)
    @array = array.map { |a| a.to_i }
  end

  def values
    @array.map { |a| quantize(a) }
  end

  def sub_total(i, j)
    @array[i..j].map { |a| quantize(a) }.reduce(:+)
  end

  private

  def quantize(val)
    (val * 100.0 / total).round(0)
  end

  def total
    @array.reduce(:+)
  end
end

以及(失败的)测试:

代码语言:javascript
复制
require 'quantize'

describe Quantize do
  context 'first example' do
    let(:subject) { described_class.new([44, 40, 7, 2, 0, 0]) }

    context '#values' do
      it 'quantizes array to add up to 100' do
        expect(subject.values).to eq([47, 43, 8, 2, 0, 0])
      end
    end

    context '#sub_total' do
      it 'adds a subset of array' do
        expect(subject.sub_total(1, 5)).to eq(53)
      end
    end
  end

  context 'second example' do
    let(:subject) { described_class.new([78, 7, 7, 1, 0, 0]) }

    context '#values' do
      it 'quantizes array to add up to 100' do
        expect(subject.values).to eq([84, 8, 8, 1, 0, 0])
      end
    end

    context '#sub_total' do
      it 'adds a subset of array' do
        expect(subject.sub_total(1, 5)).to eq(16)
      end
    end
  end
end
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-04-03 01:28:57

正如关于这个问题的注释中所指出的,量化例程没有正确地执行:第二个示例[78, 7, 7, 1, 0, 0]被量化为[84, 8, 8, 1, 0, 0] -这增加了101,而不是100。

以下是一种将产生正确结果的方法:

代码语言:javascript
复制
def quantize(array, value)
  quantized = array.map(&:to_i)
  total = array.reduce(:+)
  remainder = value - total

  index = 0

  if remainder > 0
    while remainder > 0 
      quantized[index] += 1
      remainder -= 1
      index = (index + 1) % quantized.length
    end
  else
    while remainder < 0 
      quantized[index] -= 1
      remainder += 1
      index = (index + 1) % quantized.length
    end
  end

  quantized
end

正如问题中所述,这解决了您的问题。麻烦的结果是[80, 8, 8, 2, 1, 1],它添加到100并维护您描述的子集关系。当然,这个解决方案可以变得更有表现力--但它的优势在于它的工作原理和简单易懂。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29424624

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档