书中的问题:
编写一个程序,将字母等级翻译成数字等级。字母等级为A
,B
,C
,D
和F
,可能后跟+
或–
。他们的数值是4
,3
,2
,1
和0
。没有F+
或F–
。 +
将数值增加0.3
,–
将数值减少0.3
。但是,A+
的值为4.0
。
输入字母成绩:B-
数值为2.7
。
使用方法getNumericGrade
的等级成绩。
所以我的问题是:我知道我的代码是正确的,我可以运行它。但我很好奇是否有这个代码的快捷方式或更好的版本,使它看起来更专业,更容易阅读。任何建议或例子都将非常感激。
代码:
import java.util.Scanner;
public class grade
{
private double numericValue = 0;
private String grade = "";
public grade()
{
Scanner in = new Scanner(System. in );
System.out.print("Enter Grade: ");
grade = in .nextLine();
}
public double getNumericGrade()
{
if (grade.equals("A+") || grade.equals("A"))
{
numericValue = 4.0;
}
else if (grade.equals("A-"))
{
numericValue = 3.7;
}
else if (grade.equals("B+"))
{
numericValue = 3.3;
}
else if (grade.equals("B"))
{
numericValue = 3.0;
}
else if (grade.equals("B-"))
{
numericValue = 2.7;
}
else if (grade.equals("C+"))
{
numericValue = 2.3;
}
else if (grade.equals("C"))
{
numericValue = 2.0;
}
else if (grade.equals("C-"))
{
numericValue = 1.7;
}
else if (grade.equals("D+"))
{
numericValue = 1.3;
}
else if (grade.equals("D"))
{
numericValue = 1.0;
}
else if (grade.equals("F"))
{
numericValue = 0;
}
else
{
System.out.println("Letter not in grading system");
}
return numericValue;
}
}
答案 0 :(得分:6)
您可以单独定义映射和规则:
public static enum Grade {
// Letter grades are A, B, C, D, and F
// Their numeric values are 4, 3, 2, 1, and 0
A(4),B(3),C(2),D(1),F(0);
public final double score;
private Grade(double d) {
this.score = d;
}
// Grades are possibly followed by + or –
// There is no F+ or F–
// a + increases the numeric value by 0.3, a – decreases it by 0.3
// However, an A+ has value 4.0
public double getModifiedScore(char sign) {
switch (sign) {
case '+':
return score + (score < 4 && score > 0 ? 0.3 : 0);
case '-':
return score + (score > 0 ? -0.3 : 0);
default:
throw new IllegalArgumentException("Invalid sign");
}
}
}
然后只使用它们(例子假设您已经验证了输入):
public static double getNumericGrade(String s){
Grade g = Grade.valueOf(s.substring(0, 1));
if(s.length() > 1){
return g.getModifiedScore(s.charAt(1));
}else {
return g.score;
}
}
答案 1 :(得分:5)
我会使用查找表:
private final static Map<String,Double> gradeLookup =
new HashMap<String, Double>();
gradeLookup.put("A-", 3.7);
numericValue = gradeLookup.get(grade);
另一个好的选择是switch语句,从Java 7开始,它最终适用于Strings。
这两个选项都为您提供内置输入验证,因此用户无法输入“G”或“F +”或“foo”等内容。
答案 2 :(得分:1)
使用Map
将字符(在本例中为A
.. D
,F
)映射到相应的值(4
.. {{ 1}})。
处理输入时:
0
或+
,请查找第一个字符并适当处理第二个字符(根据您发布的规则,记住处理特殊情况,例如{{ 1}})。 您可以尝试这样的事情:
-
答案 3 :(得分:1)
一种方法是使用switch
- 它与Java 7中的String
一起使用。
// Yes, I'm passing grade and shadowing numericValue, since those properties
// aren't used anywhere else in the class.
public double getNumericGrade(String grade) {
double numericValue = 0;
switch (grade) {
case "A+":
case "A":
numericValue = 4.0;
break;
case "A-":
numericValue = 3.7;
break;
case "B+":
numericValue = 3.3;
break;
case "B":
numericValue = 3.0;
break;
case "B-":
numericValue = 2.7;
break;
case "C+":
numericValue = 2.3;
break;
case "C":
numericValue = 2.0;
break;
case "C-":
numericValue = 1.7;
break;
case "D+":
numericValue = 1.3;
break;
case "D":
numericValue = 1.0;
break;
case "F":
numericValue = 0;
break;
default:
System.out.println("Letter not in grading system");
break;
}
return numericValue;
}
......但这看起来非常冗长。
另一种替代方法是采用我们对数字等级的规则,并写一些更简洁的东西。
这是一个使用这些规则的解决方案。它可能看起来更冗长,可能与开关没有什么不同,但它是写它的另一种方式。
public double getNumericGradeRefactored(String grade) {
Map<Character, Double> gradeMap = new HashMap<Character, Double>(){{
put('A', 4.0);
put('B', 3.0);
put('C', 2.0);
put('D', 1.0);
put('F', 0.0);
}};
// split result
char[] gradeParts = grade.toCharArray();
double result = gradeMap.get(gradeParts[0]);
if(gradeParts.length > 1) {
switch(gradeParts[1]) {
case '+':
result += 0.3;
break;
case '-':
result -= 0.3;
break;
}
}
return result;
}
答案 4 :(得分:0)
我会单独处理'+'或' - '。
检查字母,然后如果它包含'+'或' - ',则适当地加或减等级值。
编辑:就个人而言,我更喜欢switch-case到if if-elseif语句,但任何一个都可以运行得很好。
答案 5 :(得分:0)
除了@Thilos关于如何存储实际数据的建议之外,我想补充一点,在这种情况下,您不希望同时存储两者,在这种情况下,String
和{{1数据的版本,除非性能非常关键。
虽然现在看起来不是很重要,但在很多情况下,你会冒失去同步的风险,即int
说一件事,而String
说另一件事,你遇到了因此而产生的错误。
你的构造函数不应该提示输入,除非这变得非常普遍..采用int
更清晰。