我正在处理的程序的一部分实现了一个函数,该函数将包重量作为参数,并根据该权重计算运费。费用/磅的标准如下:
Package Weight Cost
-------------- ----
25 lbs & under $5.00 (flat rate)
26 - 50 lbs above rate + 0.10/lb over 25
50 + lbs above rate + 0.07/lb over 50
我使用了if-if else-if来进行计算,但感觉它有点重复:
const int TIER_2_WEIGHT = 25;
const int TIER_3_WEIGHT = 50;
const float TIER_1_RATE = 5.00;
const float TIER_2_RATE = 0.10;
const float TIER_3_RATE = 0.07;
float shipPriceF;
if(shipWeightF <= TIER_2_WEIGHT)
{
shipPriceF = TIER_1_RATE;
}
else if(shipWeightF <= TIER_3_WEIGHT)
{
shipPriceF = ((shipWeightF - TIER_2_WEIGHT) * TIER_2_RATE) +
TIER_1_RATE;
}
else
{
shipPriceF = ((shipWeightF - TIER_3_WEIGHT) * TIER_3_RATE) +
((TIER_3_WEIGHT - TIER_2_WEIGHT) * TIER_2_RATE) +
TIER_1_RATE;
}
return shipPriceF;
所以,问题是......这是完成这项任务的最佳方式,还是我应该寻找不同的解决方案?
答案 0 :(得分:2)
首先,你的代码看起来很清楚,确实如此。
当然,您可以使用累积方法对公式的冗余部分进行重复数据删除:
float shipPriceF = TIER_1_RATE; // to be paid anyway
if (shipWeightF > TIER_2_WEIGHT) // add the tier 2 if necessary
{
shipPriceF += (min(shipWeightF, TIER_3_WEIGHT) - TIER_2_WEIGHT) * TIER_2_RATE;
}
if(shipWeightF > TIER_3_WEIGHT) // add the tier 3 if really necessary
{
shipPriceF += (shipWeightF - TIER_3_WEIGHT) * TIER_3_RATE);
}
嗯,甚至可以进一步简化:
float shipPriceF = TIER_1_RATE
+ max(min(shipWeightF,TIER_3_WEIGHT)-TIER_2_WEIGHT,0) * TIER_2_RATE
+ max(shipWeightF-TIER_3_WEIGHT,0) * TIER_3_RATE;
对于3个量表,这个合成配方可能没问题。如果你想要更多的灵活性,你可以考虑通过速率向量迭代而不是使用常量。这将允许可变数量的尺度。如果您确定该公式始终是渐进的(例如“高于+超出新单位价格”),则使用累积方法。
答案 1 :(得分:0)
我认为代码中有很多几乎相同的行,但不是真正的重复行。如果添加更多费率,则可以轻松复制错误的宏定义或混合错误率的值。
我的代码本身删除了if / else复制,并避免使用正确的全局定义。如果您为我的代码添加新费率,只需在表格中添加原始数据即可。
只是想知道还能做些什么:
#include <iostream>
#include <functional>
#include <limits>
// first we define a entry of a table. This table contains the limit to which the ratio is valid and
// a function which calculates the price for that part of the weight.
struct RateTableEntry
{
double max;
std::function<double(double, double)> func;
};
// only to shrink the table width :-)
constexpr double MAX = std::numeric_limits<double>::max();
// and we define a table with the limits and the functions which calculates the price
RateTableEntry table[]=
{
// first is flate rate up to 25
{ 25, [](double , double )->double{ double ret= 5.00; return ret; }},
// next we have up to 50 the rate of 0.10 ( use min to get only the weight up to next limit
{ 50, [](double max, double weight)->double{ double ret= std::min(weight,max)*0.10; return ret; }},
// the same for next ratio. std::min not used, bedause it is the last entry
{ MAX, [](double , double weight)->double{ double ret= weight *0.07; return ret; }}
};
double CalcRate(double weight)
{
std::cout << "Price for " << weight;
double price = 0;
double offset = 0;
for ( auto& step: table )
{
// call each step, until there is no weight which must be calculated
price+=step.func(step.max- offset, weight);
// reduce the weight for that amount which allready is charged for
weight-=step.max-offset;
// make the table more readable, if not used this way, we have no max values but amount per step value
offset+=step.max;
if ( weight <= 0 ) break; // stop if all the weight was paid for
}
std::cout << " is " << price << std::endl;
return price;
}
int main()
{
CalcRate( 10 );
CalcRate( 26 );
CalcRate( 50 );
CalcRate( 51 );
CalcRate( 52 );
CalcRate( 53 );
}
如果C ++ 11不可用,你也可以使用普通函数和函数指针代替lambdas和std :: function。