C++ C++;根据重量计算运输成本

C++ C++;根据重量计算运输成本,c++,duplicates,control-flow,C++,Duplicates,Control Flow,我正在处理的程序的一部分实现了一个函数,该函数将包装重量作为参数,并根据该重量计算运输成本。每磅成本的标准如下: Package Weight Cost -------------- ---- 25 lbs & under $5.00 (flat rate) 26 - 50 lbs above rate + 0.10

我正在处理的程序的一部分实现了一个函数,该函数将包装重量作为参数,并根据该重量计算运输成本。每磅成本的标准如下:

        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-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;
const int TIER_2_WEIGHT=25;
第三层常数重量=50;
常数浮动层1的费率=5.00;
常数浮动第2层利率=0.10;
常数浮动第三层利率=0.07;
浮动船价f;

如果(shipWeightF首先,您的代码看起来很清晰,并且看起来还可以

当然,您可以使用累积方法消除公式中的冗余部分:

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个标度,这个合成公式可能没问题。但是,如果你想要更大的灵活性,你可以考虑迭代速率向量,而不是使用常数。这将允许可变数量的标度。如果你确定公式总是渐进的(例如,“高于+超出部分的新单价”)然后使用累积法。

我认为代码中有很多几乎相同的行,但不是真正的重复行。如果添加更多的速率,则可以轻松复制错误的宏定义或混合错误速率中的值

我的代码本身删除了if/else复制,避免了使用正确的全局定义。如果向我的代码中添加新速率,只需向表中添加一个raw

只是想知道还能做些什么:

#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 );
}
#包括
#包括
#包括
//首先,我们定义一个表的条目。这个表包含比率的有效和有效极限
//计算该部分重量价格的函数。
结构RateTableEntry
{
双峰;
std::函数func;
};
//仅收缩表格宽度:-)
constexpr double MAX=std::numeric_limits::MAX();
//我们定义了一个表格,里面有计算价格的极限和函数
RateTableEntry表[]=
{
//首先是最高25%的贷款利率
{25,[](double,double)->double{double ret=5.00;return ret;},
//接下来,我们将以0.10的速率将重量增加到50(使用min仅将重量增加到下一个极限)
{50,[](双倍最大值,双倍重量)->double{double ret=std::min(重量,最大值)*0.10;return ret;},
//下一个比率也一样。std::min未使用,因为它是最后一个条目
{MAX,[](双重,双重重量)->double{double-ret=weight*0.07;return-ret;}
};
双板条箱(双倍重量)
{

std::cout就良好实践而言,你拥有的是完美的。就你使用if-else-if-else而言,没有重复。此外,这里没有递归。假设这些是唯一的层次,这看起来很好。感谢反馈!这更多是我的想法,但无法想清楚。非常感谢d!虽然您的解决方案被简化了,但在效率方面会有任何折衷吗?第一个使用的比较操作比我原来的少一个,但是您发布的最后一个使用了几个min/maxes。如果速率级数更大,会有什么不同吗?您确实是对的,但这在很大程度上取决于优化器。例如,在GCC 6.2中,my只比您的少一条asm指令,my多4条指令。但总体执行性能不仅取决于指令数,还取决于权重的统计分布(需要更多或更少的跳跃)。因此,我的adivce:“过早优化是万恶之源”。