2

これまでのところ、次のプログラムがあります。

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;
        }
    }
}

時速 125 マイルまで、1 年から 4 年までのこれらのステートメントの完全なリストがあります。車両の速度を入力して、速度に応じて適切なチケット情報を提供するプログラムを作成しようとしています。

制限速度は時速15マイルです。制限速度を時速 5 マイル超過するごとに、総額に $87.50 が追加されます。Year 2 は 2 年生なので、$50.00 の割引が適用されます。しかし、同様に 4 年目には、$100.00 の料金が合計に追加されます。各速度で同じ合計を取得しています。なんで?

4

9 に答える 9

1

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

これを「速度は 50 から 54 の間」という意味にしたい場合は、ロジックに問題があります。あなたが欲しいか、そうでないか。

誰かをそこに案内するのではなく、実際の答えを提供することで、この辺りのエチケットが何であるかはわかりませんが、これはあなたが目指すべきものです. 私は個人的にそれをテストしていません。

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;

}
于 2009-04-05T19:24:54.690 に答える
0

ねえ、私は少し混乱しています。

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

?

于 2009-04-05T19:25:11.770 に答える
0

演算子の優先順位とセマンティクスを混同していると思います。

まず、 (speed >=50) && (speed <= 54) と言いたい

次に、C では && の優先順位が高いため、そのままの式は次のようになります。 If (year==1 AND speed>=50) OR (if my speed is low than 54)...

3 番目に、余分な () のペアがあり、別の優先順位を付けるつもりだったことを示しています。

最後に、似たように見える if ステートメントがたくさんあるコードは、かなり不適切に記述されていることに言及します。それを実装するためのより良い方法は、範囲を表すテーブルまたはデータ構造、または少なくともより良い編成のいずれかです。

====

更新:コードを投稿したので、これに一生懸命取り組んでいるように見えます...まず、年に基づいて if または switch します(約4年しかないはずです)。毎年、別の関数を呼び出して計算を行います。これにより、すでにクリーンになります。例えば:

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

(C# はわかりませんが、ある種の switch ステートメントがあるはずです)

これで、毎年個別に管理できます。条件は速度の昇順であるため、次のようにすることができます。

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

まだ完璧にはほど遠いですが、すでにかなりクリーンで扱いやすいものになっています。

ここで、if を見ると、50 + C*diff を支払っているので、それほど多くの if は必要ないように見えます。計算?

例えば:

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))

(私はC#を知りません、構文を推測しているだけです)

于 2009-04-05T19:26:08.133 に答える
0

あなたのコードが何をしようとしているのか 100% 確信があるかどうかはわかりませんが、問題は論理演算子の優先順位にかかっています。

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

速度の不等式を囲む余分な括弧に注意してください。

于 2009-04-05T19:26:43.780 に答える
0

ここでは、テーブル駆動のアプローチがうまく機能するはずです。テーブルで値を定義し、それらを繰り返し処理して一致する値を見つけ、それを使用して計算を行います。これはうまく機能し、コードにまったく触れずにエントリを簡単に追加/編集/削除できます。

単純な静的に割り当てられ、定義されたテーブルから始めることができます。必要に応じて、XML ファイルなどの別のソースからテーブルを動的にロードできます。

于 2009-04-06T01:02:56.750 に答える
0

これらの if 文には目が充血し、一貫性もありません。最初の範囲の速度に誤りがあります。1 年目で速度が 15 の場合、罰金が科せられます。if ステートメントの長い行を使用するものもあれば、if/elseif ステートメントを使用するものもあります。違いがあります - 特に速度 <= 数値かどうかをテストしている場合。(|| または句を含む一連の if ステートメントはそれぞれ true と評価され、if/else ステートメントは最初のステートメントのみを評価します)。|| の代わりに && (and) を意味していた可能性があります。(または) - しかし、すべての人の正気のために、これらの if ステートメントを置き換える必要があります。;)

結果ではなく、式を考え出し、それをコーディングます。[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);

これは次のように簡略化できます。

    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;
    }

ただし、年部分のネストされた 3 項式について口論する人もいます。

[1] 技術的には、125 を超えるものは罰金 0 ドルですが、それはあなたが望んでいたことではないと思います。

于 2009-04-05T20:10:21.727 に答える