今週は、利益を計算する簡単なアルゴリズムの問題です。TDD の原則を使用して開発し、問題を解決するためにいくつかの異なる方法を使用する予定です。
TDD と gtest に関する前回の記事をまだ読んでいない場合は、次のアドレスを参照することをお勧めします。
トピック: ボーナスの計算
トピック:
企业发放的奖金根据利润提成。利润低于或等于100000元的,奖金可提10%;
利润高于100000元,低于200000元(100000<I≤200000)时,低于100000元的部分按10%提成,高于100000元的部分,可提成 7.5%;
200000<I≤400000时,低于200000元部分仍按上述办法提成,(下同),高于200000元的部分按5%提成;
400000<I≤600000元时,高于400000元的部分按3%提成;
600000<I≤1000000时,高于600000元的部分按1.5%提成;
I>1000000时,超过1000000元的部分按1%提成。
方法 1: if more else if
最も一般的な解決策であるはずです。
前回の記事の構成に従い、gtest 環境を構築します。各部分のコードは次のとおりです。
BonusMoney.h
コードは以下のように表示されます:
int bonus(int moneyGet);
BonusMoney.cpp
コードは以下のように表示されます:
#include "BonusMoney.h"
int bonus(int moneyGet)
{
int bonus = 0;
if (moneyGet <= 100000)
bonus = 0.1 * moneyGet;
else if (moneyGet <= 200000)
bonus = 0.1 * 100000 + 0.075 * (moneyGet - 100000);
else if (moneyGet <= 400000)
bonus = 0.1 * 100000 + 0.075 * 100000 + 0.05 * (moneyGet - 200000);
else if (moneyGet <= 600000)
bonus = 0.1 * 100000 + 0.075 * 100000 + 0.05 * 200000 + 0.03 * (moneyGet - 400000);
else if (moneyGet <= 1000000)
bonus = 0.1 * 100000 + 0.075 * 100000 + 0.05 * 200000 + 0.03 * 200000 + 0.015 * (moneyGet - 600000);
else
bonus = 0.1 * 100000 + 0.075 * 100000 + 0.05 * 200000 + 0.03 * 200000 + 0.015 * 400000 + 0.01 * (moneyGet - 1000000);
return bonus;
}
BonusMoney_unittest.cpp
コードは以下のように表示されます:
#include "gtest/gtest.h"
#include "BonusMoney.h"
TEST(bonusMoneyTest, moneyGet_10000)
{
EXPECT_EQ(bonus(10000), 0.1 * 10000);
}
TEST(bonusMoneyTest, moneyGet_110000)
{
EXPECT_EQ(bonus(110000), 0.1 * 100000 + 0.075 * (110000 - 100000));
}
TEST(bonusMoneyTest, moneyGet_210000)
{
EXPECT_EQ(bonus(210000), 0.1 * 100000 + 0.075 * 100000 + 0.05 * (210000 - 200000));
}
TEST(bonusMoneyTest, moneyGet_410000)
{
EXPECT_EQ(bonus(410000), 0.1 * 100000 + 0.075 * 100000 + 0.05 * 200000 + 0.03 * (410000 - 400000));
}
TEST(bonusMoneyTest, moneyGet_610000)
{
EXPECT_EQ(bonus(610000), 0.1 * 100000 + 0.075 * 100000 + 0.05 * 200000 + 0.03 * 200000 + 0.015 * (610000 - 600000));
}
TEST(bonusMoneyTest, moneyGet_1100000)
{
EXPECT_EQ(bonus(1100000), 0.1 * 100000 + 0.075 * 100000 + 0.05 * 200000 + 0.03 * 200000 + 0.015 * 400000 + 0.01 * (1100000 - 1000000));
}
int main(int argc, char **argv)
{
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
方法 2: スイッチケース
この方法の原理を説明する前に、switch-case
それほど特別ではないかもしれない特別な使用法を紹介しましょう。
一般的に、Switch-case
各構造内のコードは で終わりcase
ますbreak
。これは、 が飛び出すことを意味しますswitch
。
switch(...):
case a:
...;
break;
case b:
... ...
使用しない場合break
、他のコードはcase
次のコードが見つかるまで順次実行され続けますbreak
。この現象は浸透と呼ばれます。侵入は回避する必要があるバグだと常々思っていましたが、実際には悪用できる機能でもあります。
ペネトレーションでは、一致したケースの背後にあるすべての作業コードが実行されるため、考え方を逆転させて、最大のケースからマッチングを開始できます (最大は無限であるため、最大の一致をデフォルトに置きます)。範囲内で一致できる場合 (結局のところ、すべての数値の大文字と小文字を区別することはできません)、/
範囲変換を使用します。
switch (moneyGet / 100000)
{
default:
moneyGet -= 1000000;
profit += moneyGet * 0.01;
moneyGet = 1000000;
各レンジの利益が差し引かれ、賞金が合計されます。1つずつ浸透させるには次の手順を実行します。
case 9:
case 8:
case 7:
case 6:
moneyGet -= 600000;
profit += moneyGet * 0.015;
moneyGet = 600000;
BonusMoneySwitch.cpp
完全なコードは次のとおりです。
int bonusSwitch(int moneyGet)
{
int profit = 0;
switch (moneyGet / 100000)
{
default:
moneyGet -= 1000000;
profit += moneyGet * 0.01;
moneyGet = 1000000;
case 9:
case 8:
case 7:
case 6:
moneyGet -= 600000;
profit += moneyGet * 0.015;
moneyGet = 600000;
case 5:
case 4:
moneyGet -= 400000;
profit += moneyGet * 0.03;
moneyGet = 400000;
case 3:
case 2:
moneyGet -= 200000;
profit += moneyGet * 0.05;
moneyGet = 200000;
case 1:
moneyGet -= 100000;
profit += moneyGet * 0.075;
moneyGet = 100000;
case 0:
profit += moneyGet * 0.1;
}
return profit;
}
対応する gtest は完全には記述されていません。例を 1 つだけ示します。
TEST(bonusMoneyTest, moneyGet_1100000)
{
EXPECT_EQ(bonus(1100000), 0.1 * 100000 + 0.075 * 100000 + 0.05 * 200000 + 0.03 * 200000 + 0.015 * 400000 + 0.01 * (1100000 - 1000000));
EXPECT_EQ(bonusSwitch(1100000), 0.1 * 100000 + 0.075 * 100000 + 0.05 * 200000 + 0.03 * 200000 + 0.015 * 400000 + 0.01 * (1100000 - 1000000));
}
もちろん、この質問は肯定的な switch-case を使用して行うこともできますが、これは if-else 構造に似ています。
他のソリューション
付け加えますと、今週は外食なので疲れていて、ちょっと水っぽい記事になってしまいましたが、ご容赦ください。