简体   繁体   English

减少if语句的数量

[英]Reducing the number of if statements

I have the following program so far: 到目前为止我有以下程序:

using System;
namespace ParkingTicket
{
    class Program
    {
        static void Main()
        {
            int speed;
            int yrInSchool;
            double fine;
            char choice = ' ';
            do
            {
                Console.Clear();
                speed = GetSpeed();
                if (speed <= 15)
                    Console.WriteLine("No speeding fine to pay.");
                else
                {
                    yrInSchool = GetYrInSchool();
                    fine = CalculateFine(speed, yrInSchool);
                    DisplayFine(fine);
                }
                choice = GetUserChoice();
            } while (choice != 'Q' && choice != 'q');
        }
        static int GetSpeed()
        {
            int speed;
            string userInput;
            try
            {
                Console.Write("Please enter the speed you were traveling: ");
                userInput = Console.ReadLine();
                speed = Convert.ToInt32(userInput);
            }
            catch
            {
                Console.WriteLine("\a\n INVALID - PLEASE TRY AGAIN");
                Console.Write("Please press enter to continue....");
                userInput = Console.ReadLine();
                speed = GetSpeed();  // this is the recursion - calling myself

            }
            return speed;

            // code this method
        }
        static int GetYrInSchool()
        {
            string userEntry;
            int year;

            /*************************************************************
             *  modify this method to validate the year using a Try/Catch
             *************************************************************/
            Console.WriteLine("\nClassifications");
            Console.WriteLine("\tFreshman  (enter 1)");
            Console.WriteLine("\tSophomore (enter 2)");
            Console.WriteLine("\tJunior    (enter 3)");
            Console.WriteLine("\tSenior    (enter 4)");

            try
            {
                Console.Write("Enter choice: ");
                userEntry = Console.ReadLine();
                year = Convert.ToInt32(userEntry);
            }

            catch
            {
                Console.WriteLine("\a\n INVALID - PLEASE TRY AGAIN");
                Console.Write("Please press enter to continue....");
                userEntry = Console.ReadLine();
                year = GetYrInSchool();  // this is the recursion - calling myself
            }
            return year;
        }
        static double CalculateFine(int speed, int year)
        {
            const double COST_PER_5_OVER = 87.50;
            const int SPEED_LIMIT = 15;
            const double INITIAL_FEE = 75.00;
            double fine = 0;

            if (((year == 1) && (speed >= 15) || (speed <= 19)))
            {
                fine = INITIAL_FEE - 50.00;
            }
            else if (((year == 1) && (speed >= 20) || (speed >= 24)))
            {
                fine += (INITIAL_FEE - 50.00) + COST_PER_5_OVER;
            }
            else if (((year == 1) && (speed >= 25) || (speed <= 29)))
            {
                fine = (INITIAL_FEE - 50.00) + (COST_PER_5_OVER * 2);
            }
            else if (((year == 1) && (speed >= 30) || (speed <= 34)))
                fine = (INITIAL_FEE - 50.00) + (COST_PER_5_OVER * 3);
            else if (((year == 1) && (speed >= 35) || (speed <= 39)))
                fine = (INITIAL_FEE - 50.00) + (COST_PER_5_OVER * 4);
            else if (((year == 1) && (speed >= 40) || (speed <= 44)))
                fine = (INITIAL_FEE - 50.00) + (COST_PER_5_OVER * 5);
            else if (((year == 1) && (speed >= 45) || (speed <= 49)))
                fine = (INITIAL_FEE - 50.00) + (COST_PER_5_OVER * 6);
            if (((year == 1) && (speed >= 50) || (speed <= 54)))
                fine = (INITIAL_FEE - 50.00) + (COST_PER_5_OVER * 7);
            if (((year == 1) && (speed >= 55) || (speed <= 59)))
                fine = (INITIAL_FEE - 50.00) + (COST_PER_5_OVER * 8);
            if (((year == 1) && (speed >= 60) || (speed <= 64)))
                fine = (INITIAL_FEE - 50.00) + (COST_PER_5_OVER * 9);
            if (((year == 1) && (speed >= 65) || (speed <= 69)))
                fine = (INITIAL_FEE - 50.00) + (COST_PER_5_OVER * 10);
            if (((year == 1) && (speed >= 70) || (speed <= 74)))
                fine = (INITIAL_FEE - 50.00) + (COST_PER_5_OVER * 11);
            if (((year == 1) && (speed >= 75) || (speed <= 79)))
                fine = (INITIAL_FEE - 50.00) + (COST_PER_5_OVER * 12);
            if (((year == 1) && (speed >= 80) || (speed <= 84)))
                fine = (INITIAL_FEE - 50.00) + (COST_PER_5_OVER * 13);
            if (((year == 1) && (speed >= 85) || (speed <= 89)))
                fine = (INITIAL_FEE - 50.00) + (COST_PER_5_OVER * 14);
            if (((year == 1) && (speed >= 90) || (speed <= 94)))
                fine = (INITIAL_FEE - 50.00) + (COST_PER_5_OVER * 15);
            if (((year == 1) && (speed >= 95) || (speed <= 99)))
                fine = (INITIAL_FEE - 50.00) + (COST_PER_5_OVER * 16);
            if (((year == 1) && (speed >= 100) || (speed <= 104)))
                fine = (INITIAL_FEE - 50.00) + (COST_PER_5_OVER * 17);
            if (((year == 1) && (speed >= 105) || (speed <= 109)))
                fine = (INITIAL_FEE - 50.00) + (COST_PER_5_OVER * 18);
            if (((year == 1) && (speed >= 110) || (speed <= 114)))
                fine = (INITIAL_FEE - 50.00) + (COST_PER_5_OVER * 19);
            if (((year == 1) && (speed >= 115) || (speed <= 119)))
                fine = (INITIAL_FEE - 50.00) + (COST_PER_5_OVER * 20);
            if (((year == 1) && (speed >= 120) || (speed <= 124)))
                fine = (INITIAL_FEE - 50.00) + (COST_PER_5_OVER * 21);
            else if (((year == 2) && (speed >= 16) || (speed <= 19)))
                fine = INITIAL_FEE;
            if (((year == 2) && (speed >= 20) || (speed <= 24)))
                fine = INITIAL_FEE + (COST_PER_5_OVER);
            if (((year == 2) && (speed >= 25) || (speed <= 29)))
                fine = INITIAL_FEE + (COST_PER_5_OVER * 2);
            if (((year == 2) && (speed >= 30) || (speed <= 34)))
                fine = INITIAL_FEE + (COST_PER_5_OVER * 3);
            if (((year == 2) && (speed >= 35) || (speed <= 39)))
                fine = INITIAL_FEE + (COST_PER_5_OVER * 3);
            if (((year == 2) && (speed >= 40) || (speed <= 44)))
                fine = INITIAL_FEE + (COST_PER_5_OVER * 4);
            if (((year == 2) && (speed >= 45) || (speed <= 49)))
                fine = INITIAL_FEE + (COST_PER_5_OVER * 5);
            if (((year == 2) && (speed >= 50) || (speed <= 54)))
                fine = INITIAL_FEE + (COST_PER_5_OVER * 6);
            if (((year == 2) && (speed >= 55) || (speed <= 59)))
                fine = INITIAL_FEE + (COST_PER_5_OVER * 7);
            if (((year == 2) && (speed >= 60) || (speed <= 64)))
                fine = INITIAL_FEE + (COST_PER_5_OVER * 8);
            if (((year == 2) && (speed >= 65) || (speed <= 69)))
                fine = INITIAL_FEE + (COST_PER_5_OVER * 9);
            if (((year == 2) && (speed >= 70) || (speed <= 74)))
                fine = INITIAL_FEE + (COST_PER_5_OVER * 10);
            if (((year == 2) && (speed >= 75) || (speed <= 79)))
                fine = INITIAL_FEE + (COST_PER_5_OVER * 11);
            if (((year == 2) && (speed >= 80) || (speed <= 84)))
                fine = INITIAL_FEE + (COST_PER_5_OVER * 12);
            if (((year == 2) && (speed >= 85) || (speed <= 89)))
                fine = INITIAL_FEE + (COST_PER_5_OVER * 13);
            if (((year == 2) && (speed >= 90) || (speed <= 94)))
                fine = INITIAL_FEE + (COST_PER_5_OVER * 14);
            if (((year == 2) && (speed >= 95) || (speed <= 99)))
                fine = INITIAL_FEE + (COST_PER_5_OVER * 15);
            if (((year == 2) && (speed >= 100) || (speed <= 104)))
                fine = INITIAL_FEE + (COST_PER_5_OVER * 16);
            if (((year == 2) && (speed >= 105) || (speed <= 109)))
                fine = INITIAL_FEE + (COST_PER_5_OVER * 17);
            if (((year == 2) && (speed >= 110) || (speed <= 114)))
                fine = INITIAL_FEE + (COST_PER_5_OVER * 18);
            if (((year == 2) && (speed >= 115) || (speed <= 119)))
                fine = INITIAL_FEE + (COST_PER_5_OVER * 19);
            if (((year == 2) && (speed >= 120) || (speed <= 124)))
                fine = INITIAL_FEE + (COST_PER_5_OVER * 20);
            if (((year == 2) && (speed >= 125) || (speed <= 129)))
                fine = INITIAL_FEE + (COST_PER_5_OVER * 21);
            else if (((year == 3) && (speed >= 16) || (speed <= 19)))
                fine = INITIAL_FEE + 50.00;
            if (((year == 3) && (speed >= 20) || (speed <= 24)))
                fine = INITIAL_FEE + 50.00 + (COST_PER_5_OVER);
            if (((year == 3) && (speed >= 25) || (speed <= 29)))
                fine = (INITIAL_FEE + 50.00) + (COST_PER_5_OVER * 2);
            if (((year == 3) && (speed >= 30) || (speed <= 34)))
                fine = (INITIAL_FEE + 50.00) + (COST_PER_5_OVER * 3);
            if (((year == 3) && (speed >= 35) || (speed <= 39)))
                fine = (INITIAL_FEE + 50.00) + (COST_PER_5_OVER * 4);
            if (((year == 3) && (speed >= 40) || (speed <= 44)))
                fine = (INITIAL_FEE + 50.00) + (COST_PER_5_OVER * 5);
            if (((year == 3) && (speed >= 45) || (speed <= 49)))
                fine = (INITIAL_FEE + 50.00) + (COST_PER_5_OVER * 6);
            if (((year == 3) && (speed >= 50) || (speed <= 54)))
                fine = (INITIAL_FEE + 50.00) + (COST_PER_5_OVER * 7);
            if (((year == 3) && (speed >= 55) || (speed <= 59)))
                fine = (INITIAL_FEE + 50.00) + (COST_PER_5_OVER * 8);
            if (((year == 3) && (speed >= 60) || (speed <= 64)))
                fine = (INITIAL_FEE + 50.00) + (COST_PER_5_OVER * 9);
            if (((year == 3) && (speed >= 65) || (speed <= 69)))
                fine = (INITIAL_FEE + 50.00) + (COST_PER_5_OVER * 10);
            if (((year == 3) && (speed >= 70) || (speed <= 74)))
                fine = (INITIAL_FEE + 50.00) + (COST_PER_5_OVER * 11);
            if (((year == 3) && (speed >= 75) || (speed <= 79)))
                fine = (INITIAL_FEE + 50.00) + (COST_PER_5_OVER * 12);
            if (((year == 3) && (speed >= 80) || (speed <= 84)))
                fine = (INITIAL_FEE + 50.00) + (COST_PER_5_OVER * 13);
            if (((year == 3) && (speed >= 85) || (speed <= 89)))
                fine = (INITIAL_FEE + 50.00) + (COST_PER_5_OVER * 14);
            if (((year == 3) && (speed >= 90) || (speed <= 94)))
                fine = (INITIAL_FEE + 50.00) + (COST_PER_5_OVER * 15);
            if (((year == 3) && (speed >= 95) || (speed <= 99)))
                fine = (INITIAL_FEE + 50.00) + (COST_PER_5_OVER * 16);
            if (((year == 3) && (speed >= 100) || (speed <= 104)))
                fine = (INITIAL_FEE + 50.00) + (COST_PER_5_OVER * 17);
            if (((year == 3) && (speed >= 105) || (speed <= 109)))
                fine = (INITIAL_FEE + 50.00) + (COST_PER_5_OVER * 18);
            if (((year == 3) && (speed >= 110) || (speed <= 114)))
                fine = (INITIAL_FEE + 50.00) + (COST_PER_5_OVER * 19);
            if (((year == 3) && (speed >= 115) || (speed <= 119)))
                fine = (INITIAL_FEE + 50.00) + (COST_PER_5_OVER * 20);
            if (((year == 3) && (speed >= 120) || (speed <= 124)))
                fine = (INITIAL_FEE + 50.00) + (COST_PER_5_OVER * 21);
            else if (((year == 4) && (speed >= 16) || (speed <= 19)))
                fine = INITIAL_FEE + 100.00;
            if (((year == 4) && (speed >= 20) || (speed <= 24)))
                fine = (INITIAL_FEE + 100.00) + (COST_PER_5_OVER);
            if (((year == 4) && (speed >= 25) || (speed <= 29)))
                fine = (INITIAL_FEE + 100.00) + (COST_PER_5_OVER * 2);
            if (((year == 4) && (speed >= 30) || (speed <= 34)))
                fine = (INITIAL_FEE + 100.00) + (COST_PER_5_OVER * 3);
            if (((year == 4) && (speed >= 35) || (speed <= 39)))
                fine = (INITIAL_FEE + 100.00) + (COST_PER_5_OVER * 4);
            if (((year == 4) && (speed >= 40) || (speed <= 44)))
                fine = (INITIAL_FEE + 100.00) + (COST_PER_5_OVER * 5);
            if (((year == 4) && (speed >= 45) || (speed <= 49)))
                fine = (INITIAL_FEE + 100.00) + (COST_PER_5_OVER * 6);
            if (((year == 4) && (speed >= 100) || (speed <= 54)))
                fine = (INITIAL_FEE + 100.00) + (COST_PER_5_OVER * 7);
            if (((year == 4) && (speed >= 55) || (speed <= 59)))
                fine = (INITIAL_FEE + 100.00) + (COST_PER_5_OVER * 8);
            if (((year == 4) && (speed >= 60) || (speed <= 64)))
                fine = (INITIAL_FEE + 100.00) + (COST_PER_5_OVER * 9);
            if (((year == 4) && (speed >= 65) || (speed <= 69)))
                fine = (INITIAL_FEE + 100.00) + (COST_PER_5_OVER * 10);
            if (((year == 4) && (speed >= 70) || (speed <= 74)))
                fine = (INITIAL_FEE + 100.00) + (COST_PER_5_OVER * 11);
            if (((year == 4) && (speed >= 75) || (speed <= 79)))
                fine = (INITIAL_FEE + 100.00) + (COST_PER_5_OVER * 12);
            if (((year == 4) && (speed >= 80) || (speed <= 84)))
                fine = (INITIAL_FEE + 100.00) + (COST_PER_5_OVER * 13);
            if (((year == 4) && (speed >= 85) || (speed <= 89)))
                fine = (INITIAL_FEE + 100.00) + (COST_PER_5_OVER * 14);
            if (((year == 4) && (speed >= 90) || (speed <= 94)))
                fine = (INITIAL_FEE + 100.00) + (COST_PER_5_OVER * 15);
            if (((year == 4) && (speed >= 95) || (speed <= 99)))
                fine = (INITIAL_FEE + 100.00) + (COST_PER_5_OVER * 16);
            if (((year == 4) && (speed >= 100) || (speed <= 104)))
                fine = (INITIAL_FEE + 100.00) + (COST_PER_5_OVER);
            if (((year == 4) && (speed >= 105) || (speed <= 109)))
                fine = (INITIAL_FEE + 100.00) + (COST_PER_5_OVER * 18);
            if (((year == 4) && (speed >= 110) || (speed <= 114)))
                fine = (INITIAL_FEE + 100.00) + (COST_PER_5_OVER * 19);
            if (((year == 4) && (speed >= 115) || (speed <= 119)))
                fine = (INITIAL_FEE + 100.00) + (COST_PER_5_OVER * 20);
            if (((year == 4) && (speed >= 120) || (speed <= 124)))
                fine = (INITIAL_FEE + 100.00) + (COST_PER_5_OVER * 21);

            // finish coding this method

            return fine;
        }

        static void DisplayFine(double fine)
        {
            Console.WriteLine("Fine: {0:C}", fine);
        }

        static char GetUserChoice()
        {
            Console.Write
                ("\nPress \"C\" to [C]ontinue or \"Q\" to [Q]uit: ");
            string userEntry = Console.ReadLine();
            char choice = Convert.ToChar(userEntry);
            Console.WriteLine("------------------------------------");
            return choice;
        }
    }
}

I have a whole list of these statements going up to 125 mph and for different years: 1 through 4. I'm trying to make a program that takes input for speed of a vehicle, then gives appropriate ticket information according to speed. 我有一个完整的列表,这些声明高达125英里/小时和不同年份:1到4.我正在尝试制作一个程序,接受车辆的速度输入,然后根据速度提供适当的票务信息。

The speed limit is 15 mph. 限速为15英里/小时。 For every 5 miles per hour over speed limit, $87.50 is added towards the total. 每超过5英里的速度限制,总计增加87.50美元。 Year 2 is sophomore so a $50.00 discount applies. 2年级是大二学生,因此需要50.00美元的折扣。 Yet for like year 4, a $100.00 fee is added towards the total. 然而,就像第4年一样,总额增加了100美元的费用。 I am getting same total for each speed. 我为每个速度得到相同的总数。 Why? 为什么?

What others have said about operator precedence seems to be correct, but I think there is a bigger issue here. 其他人对运营商优先权的看法似乎是正确的,但我认为这里有一个更大的问题。 You really shouldn't need zillions of if-statements to model this problem. 你真的不需要数以万计的if语句来模拟这个问题。 I'm sure you've found out by now that this method is not maintainable. 我相信你现在已经发现这种方法不可维护。 Trying to change anything in that pile of ifs is going to be a real pain and very error prone. 试图改变那堆ifs中的任何东西将是一个真正的痛苦并且非常容易出错。

First thing I would do is separate the calculation for the discount from the calculation for the fine. 我要做的第一件事是将折扣的计算与罚款的计算分开。 This way you do not have to manually calculate every possible combination of discount and fine. 这样您就不必手动计算折扣和罚款的每种可能组合。 Here's what I'm talking about: 这就是我所说的:

static double CalculateFine(int speed, int year)
{
    const double COST_PER_5_OVER = 87.5;
    const int SPEED_LIMIT = 15;
    const double INITIAL_FEE = 75;

    // Should there be a fine at all?
    if (speed > SPEED_LIMIT) {
        // The discount is 50 for each year, scaled so that year 1 is
        // -50, year 2 is 0, and so on.
        double discount = year * 50 - 100;

        // Now calculate the standard fee.
        int feeMultiplier = (speed - SPEED_LIMIT) / 5;
        double fine = feeMultiplier * COST_PER_5_OVER + INITIAL_FEE;

        return discount + fine;
    }
    return 0.;
}

In the end, the discount and fine are combined only one time. 最后,折扣和罚款仅合并一次。 Really, this is just figuring out what formula is used to calculate the fine and then implementing that. 真的,这只是弄清楚用什么公式来计算罚款,然后实施。 If the fine were defined in a more arbitrary manner then perhaps a table would be useful. 如果以更随意的方式定义罚款,那么表格可能是有用的。

(speed >= 50) || (speed <= 54)

If you want this to mean "speed is between 50 and 54", your logic is faulty. 如果您希望这意味着“速度在50到54之间”,那么您的逻辑就会出错。 You want and, not or. 你想要而不是或。

I don't know what the etiquette is around here in supplying an actual answer as opposed to guiding someone there, but this is the kind of thing you should aim for. 我不知道这里的礼仪是什么提供了一个实际的答案,而不是在那里指导某人,但这是你应该瞄准的事情。 I haven't tested it personally though. 我没有亲自测试过。

static double CalculateFine(int speed, int year)
{
    const double COST_PER_5_OVER = 87.50;
    const int SPEED_LIMIT = 15;
    const double INITIAL_FEE = 75.00;
    double fine = 0;

    if(speed <= SPEED_LIMIT)
    {
        return 0; // No fine imposed
    }

    fine = INITIAL_FEE;

    // Adjust for the different years
    switch(year) {
        case 1:
            fine -= 50;
            break;
        case 2:
            // nowt
            break;
        case 3:
            fine += 50;
            break;
        case 4:
            fine += 100;
    }

    // Add the remaining fine for each 5 miles over the limit
    // XXX: This is slightly different from yours, in that past 125,
    // it'll still keep adding COST_PER_5_OVER
    int perFiveOver = (int)Math.Floor((speed - SPEED_LIMIT) / 5);
    fine += (perFiveOver * COST_PER_5_OVER);

    return fine;

}

Well this isn't a direct answer (I think other people have covered that pretty well) you may want to check out the book Code Complete by Steve McConnell. 嗯,这不是一个直接的答案(我认为其他人已经很好地介绍了)你可能想看看史蒂夫麦康奈尔的书代码完成 It contains best practices to avoid code like you have above. 它包含避免上述代码的最佳实践。 It could help you out for future projects. 它可以帮助您完成未来的项目。

如果If语句至少包含一个或多个'嵌套'If语句,通常会使用switch语句...

Hey, I'm a little confused, should it be 嘿,我有点困惑,不应该

((year == 1) && (speed >= 50) && (speed <= 54))

?

I think you're confusing your operator precedence and semantics. 我认为你混淆了运算符的优先级和语义。

First of all, you want to say (speed >=50) && (speed <= 54) 首先,你想说(速度> = 50)&&(速度<= 54)

Second, in C the && has a higher precedence, so your expression as it is means: If (year==1 AND speed>=50) OR (if my speed is lower than 54)... 其次,在C中,&&具有更高的优先级,所以你的表达式意味着:如果(年= = 1和速度> = 50)或者(如果我的速度低于54)......

Third, you have an extra pair of () which suggests that you intended to prioritize things differently. 第三,你有一对额外的()表明你打算以不同的方式对事物进行优先排序。

Finally, I'll mention that code that has a bunch of similar looking if statements is fairly poorly written. 最后,我将提到具有大量类似查找语句的代码编写得相当糟糕。 A better way to implement it would be either with tables or data structures to represent the ranges, or at least a better organization. 实现它的更好方法是使用表或数据结构来表示范围,或者至少是更好的组织。

==== ====

Update: Now that you've posted the code, it really looks like you're working too hard on this... First of all, if or switch based on year (there should only be about 4 years). 更新:现在您已经发布了代码,看起来您的工作真的很难......首先,如果或基于年份切换(应该只有大约4年)。 For each year, call a separate function to do the calculation, that will already be cleaner. 对于每年,调用一个单独的函数来进行计算,这将是更清洁的。 For example: 例如:

if(year==1) return calculateFineForYear1(speed);
if(year==2) return ...

(I don't know C#, but there should be some sort of switch statement) (我不知道C#,但应该有某种switch语句)

Now you can manage each year separately. 现在您可以分别管理每年。 Since your conditions are in an ascending order of speed, you could do something like: 由于您的条件是以速度递增的顺序,您可以执行以下操作:

if(speed<50) return 0;
if(speed<55) return ...;
if(speed<60) return ...;
if(speed<65) return ...

It is still far from perfect, but it will already be a lot cleaner and manageable. 它仍然远非完美,但它已经更加清洁和易于管理。

Now, looking at your ifs, it looks like you don't even need that many ifs, because you are paying 50 + C*diff, so why not just calculate the diff (speed-50) and then just return the result of the calculation? 现在,看看你的ifs,看起来你甚至不需要那么多ifs,因为你付的是50 + C * diff,所以为什么不只计算diff(speed-50)然后只返回结果如何计算?

For example: 例如:

Int total_above_limit = (speed – SPEED_LIMIT);
Int increments_of_5_above_limit = (total_above_limit)/5
Return ( (INITIAL_FEE – 50) + COST_PER_5_OVER*increments_of_5_above_limit))

(I don't know C#, I'm just guessing at the syntax) (我不知道C#,我只是猜测语法)

Not sure I'm 100% sure of what your code is trying to do, but is the problem down to the precedence of the logical operators ie should it be: 不确定我是100%确定您的代码尝试做什么,但问题是逻辑运算符的优先级,即应该是:

if (((year == 1) && ((speed >= 50) || (speed <= 54)))) fine = (INITIAL_FEE - 50.00) + (COST_PER_5_OVER * 7); if(((year == 1)&&((speed> = 50)||(speed <= 54))))fine =(INITIAL_FEE - 50.00)+(COST_PER_5_OVER * 7);

Note the extra brackets around the speed inequalities. 注意速度不等式周围的额外括号。

Those if statements make my eyes bleed - and they're inconsistent as well. 那些if语句让我的眼睛流血 - 而且它们也不一致。 You have an error in the speed for the first range - being year 1 and having a speed of 15 would get you fined. 你在第一个范围的速度上有一个错误 - 第1年,速度为15会让你被罚款。 In some you use a large line of if statements, in others if/elseif statements. 在某些情况下,您使用大量if语句,而在其他语句中使用/ elseif语句。 There is a difference - especially when you're testing whether speed <= some number. 有一点不同 - 尤其是当您测试速度<=某个数字时。 (A bunch of if statements with your || or clause will each evaluate to true, an if/else statements will only evaluate the 1st one). (带有||或子句的一堆if语句将各自评估为true,if / else语句将仅评估第一个语句)。 You likely meant && (and) instead of || 您可能意味着&&(和)而不是|| (or) - but you should replace those if statements for everybody's sanity. (或) - 但你应该为每个人的理智取代那些if语句。 ;) ;)

Figure out the formula, and code that - not the results. 弄清楚该式中,和代码 -不结果。 It looks like it's[1]: 它看起来像是[1]:

    const double COST_PER_5_OVER = 87.50;
    const int SPEED_LIMIT = 15;
    const double INITIAL_FEE = 75.00;

    if (speed <= SPEED_LIMIT)
    {
         return 0;
    }

    double yearSurcharge;
    switch (year)
    {
        case 1:
           yearSurcharge = -50;
           break;
        case 2:
           yearSurcharge = 0;
           break;
        case 3:
            yearSurcharge = 50;
            break;
        case 4:
            yearSurcharge = 100;
            break;
        default:
            yearSurcharge = 0;
            break;
    }

    const int NUMBER_OF_FIVE_OVER = 21;
    int numberOfFiveOver = Math.Min((speed - SPEED_LIMIT) % 5; MAX_NUMBER_OF_FIVE_OVER)

    return INITIAL_FEE + yearSurcharge + (numberOfFiveOver * COST_PER_5_OVER);

which could be simplified to the following: 可以简化为以下内容:

    if (speed > SPEED_LIMIT) {
         return INITIAL_FEE 
                + (year == 1 ? -50 : year == 3 ? 50 : year == 4 ? 100 : 0) 
                + Math.Min((speed - SPEED_LIMIT) % 5, MAX_NUMBER_OF_FIVE_OVER) * COST_PER_5_OVER;
    } else {
         return 0;
    }

though some will quibble over the nested ternaries for the year portion. 虽然有些人会对年份部分的嵌套三元组进行狡辩。

[1] Technically, you have a $0 fine for anything over 125 - but I don't think that's really what you wanted. [1]从技术上讲,你对超过125的任何东西都罚款0美元 - 但我认为这不是你想要的。

A table driven approach should work well here. 表格驱动的方法应该在这里运作良好。 Define the values in a table, then iterate over them with to find the one that matches, then use that for making the computation. 在表中定义值,然后迭代它们以找到匹配的值,然后使用它来进行计算。 This works well and you can easily add/edit/remove entries without touching the code - at all. 这很好用,您可以轻松添加/编辑/删除条目而无需触及代码 - 完全可以。

You can start with a simple statically allocated and defined table. 您可以从简单的静态分配和定义的表开始。 If needed, you could then make the table load dynamically from another source, such as an XML file. 如果需要,您可以从其他源(例如XML文件)动态加载表。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM