向量中的力的总和为100

时间:2012-10-24 00:45:31

标签: c++ vector double

我需要填充一个向量,使其保持一个权重之和,其中总和必须为100.换句话说,项目数等于除数,其值为商,以确保(强制)向量之和等于100.

像这样:100/3 = 3.333333 ......

vector[0]=33.33
vector[1]=33.34
vector[2]=33.33

这个的总和恰好是100(某种选择性舍入?) 另一个例子:100/6 = 16.66666667

vector[0]=16.67
vector[1]=16.67
vector[2]=16.66
vector[3]=16.67
vector[4]=16.67
vector[5]=16.66

我在杂货店里看到过这样的东西,11美元的售价可能是3美元,因此寄存器会显示3.67,3.66等价格。

这些值必须合计为100但我正在考虑使用epsilon进行此操作,但这不起作用。

const int divisor = 6;
const int dividend = 10;

std::vector<double> myVec;
myVec.resize(6);

for (int i = 0; i < divisor; ++i)
{
    ...some magic that I don't know how to do
}

编辑:客户希望将值存储(并显示)在固定为两位小数的值中,以便直观地看到它们添加到100。

4 个答案:

答案 0 :(得分:4)

就像评论所说的那样,以美分存储货币。

#include <vector>
#include <iostream>
#include <iomanip>

std::vector<int> function(int divisor, int total) {
    std::vector<int> myVec(divisor);
    for (int i = 0; i < divisor; ++i) {
        myVec[i] = total/divisor; //rounding down
        if (i < total%divisor) //for each leftover
           myVec[i] += 1; //add one of the leftovers
    }
    return myVec;
}

void print_dollars(int cents) {
    std::cout << (cents/100) << '.';
    std::cout << std::setw(2) << std::setfill('0') << (cents%100) << ' ';
}

int main() {
   std::vector<int> r = function(6, 10000);
   int sum=0;
   for(int i=0; i<r.size(); ++i) {
       print_dollars(r[i]);
       sum += r[i];
   }
   std::cout << '\n';
   print_dollars(sum);
}
//16.67 16.67 16.67 16.67 16.66 16.66 
//100.00

当你将100除以6时,得到16,剩下4个。这将把4个剩余部分放在向量的前四个槽中。汇编证明:http://ideone.com/jrInai

答案 1 :(得分:2)

没有一种“正确”的方法可以做到这一点。一个开始的地方是添加向量的内容,并找出100与您获得的结果之间的差异。如何将其折叠到单个项目本身就是一种启发式方法。您可以选择几条路线:

  1. 将您找到的差异除以向量中元素的数量除以向量中的每个元素。这样做的好处是,为了达到约束,它会以尽可能小的数量影响单个值。
  2. 您可能只想将差异添加到向量中的第一个或最后一个元素。这具有以下优点:矢量中最少数量的元素被修改。
  3. 您可能希望在向量中列出单独的舍入误差元素,这只是差异。这提供了最“正确”的答案,但可能不是您的用户想要的。
  4. 只有您可以根据您正在构建的应用程序决定使用哪种启发式方法。

    应该注意的是,使用浮点数(例如floatdoublelong double)可能会在存储货币值时导致错误 - 您应该使用定点十进制算术对于这样的计算,因为这是在“现实世界”中进行货币计算的方式。因为浮点内部使用基数2系统(在大多数系统上),所以在从十进制到二进制和返回的转换中会产生小的舍入误差。您可能对小值没有问题,但如果美元值很大,您将开始看到双精度中可用精度位数的问题。

答案 2 :(得分:1)

你可以分成剩下的东西,从剩余的数量中减去最后一个值。

const int divisor = 6;
const int dividend = 10;

std::vector<double> myVec;
myVec.reserve(6);
double remain = 100.0;

for (int i = divisor; i >= 1; --i)
{
    double val = remain / (double)i;
    remain -= val;
    myVec.push_back(val);
}

答案 3 :(得分:0)

在你的例子中, 100/6 = 16.67(四舍五入) 然后你只需乘以6-1 = 5得到83.35

现在您知道为了使总和恰好为100,您需要使最后一个元素的价格等于 100 - 83.35 = 16.65