0

重みの合計を保持するようにベクトルを設定する必要があります。合計は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

食料品店でこのようなことが行われているのを見たことがあります。そこでは、売り物が3ドルで11ドルになる可能性があるため、レジスターには3.67、3.66などの価格が表示されます。

イプシロンでこれを行うことを考えていましたが、値の合計は正確に100になる必要がありますが、それは機能しません。

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
}

編集:クライアントは、小数点以下2桁に固定された値に格納(および表示)された値が100に加算されることを視覚的に確認することを望んでいます。

4

4 に答える 4

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つのスロットのそれぞれに残りの4つが配置されます。コンパイルの証明:http://ideone.com/jrInai

于 2012-10-24T00:52:08.070 に答える
2

これを行うための「正しい」方法はありません。まず、ベクトルの内容を合計し、100と得られた結果の差を見つけます。それを個々のアイテムにどのように折りたたむかは、本質的にヒューリスティックです。あなたが取ることができるいくつかのルートがあります:

  1. 見つけた差をベクトル内の要素数で割ったものを、ベクトル内の各要素に追加します。これには、制約を達成するために可能な限り最小の量で個々の値に影響を与えるという利点があります。
  2. ベクトルの最初または最後の要素に差を追加したい場合があります。これには、ベクトル内の要素の数が最も少ないという利点があります。
  3. ベクトルに個別の丸め誤差要素をリストすることもできますが、これは違いになります。これは最も「正しい」答えを与えますが、ユーザーが望んでいるものではない可能性があります。

構築しているアプリケーションに基づいて、使用するヒューリスティックの種類を決定できるのはあなただけです。

浮動小数点数(、、、など)を使用すると、お金の値を格納するときにエラーが発生する可能性があることに注意してくださいfloatdoubleこのlong doubleような計算には固定小数点10進演算を使用する必要があります。これは、「現実の世界」でお金の計算が行われる方法だからです。浮動小数点は内部で基数2の記数法を使用するため(ほとんどのシステムで)、10進数から2進数への変換、およびその逆の変換で小さな丸め誤差が発生します。小さい値でも問題はないでしょうが、ドルの値が大きいと、doubleで使用できる精度の桁数に問題が発生し始めます。

于 2012-10-24T00:52:11.877 に答える
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);
}
于 2012-10-24T00:51:49.170 に答える
0

あなたの例では、100/6 = 16.67(四捨五入)次に、6-1 = 5を掛けて、83.35を取得します。

そして今、あなたは合計を正確に100にするために、最後の要素の価格を100に等しくする必要があることを知っています-83.35 = 16.65

于 2012-10-24T00:51:59.457 に答える