到目前为止,我有以下程序:
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美元。 2年级是大二学生,因此需要50.00美元的折扣。然而,就像第4年一样,总额增加了100美元的费用。我为每个速度得到相同的总数。为什么?
答案 0 :(得分:13)
其他人对运营商优先权的看法似乎是正确的,但我认为这里有一个更大的问题。你真的不需要数以万计的if语句来模拟这个问题。我相信你现在已经发现这种方法不可维护。试图改变那堆ifs中的任何东西将是一个真正的痛苦并且非常容易出错。
我要做的第一件事是将折扣的计算与罚款的计算分开。这样您就不必手动计算折扣和罚款的每种可能组合。这就是我所说的:
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.;
}
最后,折扣和罚款仅合并一次。真的,这只是弄清楚用什么公式来计算罚款,然后实施。如果以更随意的方式定义罚款,那么表格可能会有用。
答案 1 :(得分: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;
}
答案 2 :(得分:1)
这不是一个直接的答案(我认为其他人已经很好地介绍了这一点)你可能想查看Steve McConnell的书 Code Complete 。它包含避免上述代码的最佳实践。它可以帮助你完成未来的项目。
答案 3 :(得分:0)
((year == 1) && (speed >= 50) && (speed <= 54))
答案 4 :(得分:0)
我认为你混淆了运算符的优先级和语义。
首先,你想说(speed&gt; = 50)&amp;&amp; (速度&lt; = 54)
其次,在C&amp;&amp;具有更高的优先级,因此您的表达式意味着: 如果(年== 1和速度&gt; = 50)或(如果我的速度低于54)......
第三,你有一对额外的()表明你打算以不同的方式对事物进行优先排序。
最后,我会提到有一堆类似的查找语句的代码编写得相当糟糕。实现它的更好方法是使用表或数据结构来表示范围,或者至少是更好的组织。
====
更新: 现在你已经发布了代码,看起来你真的在努力工作...... 首先,如果或基于年份切换(应该只有大约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 ...
它仍然远非完美,但它已经更加清洁和易于管理。
现在,看着你的ifs,看起来你甚至不需要那么多ifs, 因为你付的是50 + C *差异, 那么为什么不只计算差异(速度-50)然后只返回计算结果呢?
例如:
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#,我只是猜测语法)
答案 5 :(得分:0)
不确定我是否100%确定您的代码尝试做什么,但问题是逻辑运算符的优先级,即应该是:
if(((year == 1)&amp;&amp;((speed&gt; = 50)||(speed&lt; = 54))))fine =(INITIAL_FEE - 50.00)+(COST_PER_5_OVER * 7);
注意速度不等式周围的额外括号。
答案 6 :(得分:0)
那些if语句让我的眼睛流血 - 而且它们也不一致。你在第一个范围的速度上有一个错误 - 第1年,速度为15会让你被罚款。在某些情况下,您使用大量if语句,而在其他语句中使用/ elseif语句。有一点不同 - 尤其是当您测试速度是否<=某个数字时。 (带有||或子句的一堆if语句将各自评估为true,if / else语句将仅评估第一个语句)。你可能意味着&amp;&amp; (和)而不是|| (或) - 但你应该为每个人的理智取代那些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;
}
虽然有些人会对年份部分的嵌套三元组进行狡辩。
[1]从技术上讲,你对超过125的任何东西都有0美元的罚款 - 但我认为这不是你想要的。
答案 7 :(得分:0)
表格驱动的方法应该在这里运作良好。在表中定义值,然后迭代它们以找到匹配的值,然后使用它来进行计算。这很好用,您可以轻松添加/编辑/删除条目而无需触及代码 - 完全可以。
您可以从简单的静态分配和定义的表开始。如果需要,您可以从其他源(例如XML文件)动态加载表。
答案 8 :(得分:0)
如果If语句至少包含一个或多个'嵌套'If语句,通常会使用switch语句...