第1关:整钱兑零
任务描述
本关任务:掌握增强赋值以及自增自减相关知识。编写一个能计算数组平均值和最大值的小程序,将大额的钱替换为等价的小货币单位。
相关知识
为了完成本关任务,你需要学习以下知识:
- 增强赋值;
- 自增与自减;
- 整钱兑零任务背景。
增强赋值
本课程之前的内容已经简要介绍了赋值操作(=)以及基本的数值操作(+、-、*、/、%)。这里要讲解的增强赋值正是将这两者结合起来使用。
增强赋值操作示例如下:
/** 代码清单 1 */int a = 10;int b = 5;a += b; // a = 15a -= b; // a = 10a *= b; // a = 50a /= b; // a = 10a %= b; // a = 0
在代码清单 1中,第 4 ~ 8 行的语句皆是对变量a赋值,会导致a被赋予新值,这便是“增强赋值”中的“赋值”,那么增强的含义是什么呢?
事实上,代码代码清单 1中的代码等价于如下代码:
/** 代码清单 2 */int a = 0;int b = 1;a = a + b; // 即 a += ba = a - b; // 即 a -= ba = a * b; // 即 a *= ba = a / b; // 即 a /= ba = a % b; // 即 a %= b
可见,增强赋值类似于一种简略写法。此外需要注意的是,增强赋值与赋值一样,既可以作为语句,也可以作为表达式。 示例如下:
/** 代码清单 3 */int a = 0;a += 2; // 这里的增强赋值是一个语句System.out.println(a+=2); // 这里的增强赋值是一个表达式
输出:
4
自增与自减
自增操作符(++)以及自减操作符 (--)是对变量进行“加一”或者“减一”的操作。 示例如下:
/** 代码清单 4 */int i = 3;int j = 3;// 自增i++;// 自减j--;System.out.println(i);System.out.println(j);
输出:
42
其实i++可以理解为是i=i+1或i+=1的简便写法,因为在编程的过程中,这样的操作会经常用到,尤其是在循环结构中,在课程后续课程的任务中你将经常用到自增与自减。
另外,++和--还可以放在变量的前方,写成++i、--j这样的形式,这种前置的写法在操作变量值上没有区别,但在作为表达式传值时会有“传新值”还是“传旧值”上的区别。
示例如下:
/** 代码清单 5 */int i = 3;int j = 3;// 自增作为语句i++; // 自增后 i 的值变为 4++j; // 自增后 j 的值变为 4// 自增作为表达式int a = i++; // 自增后置写法,表达式传递旧值 4int b = ++j; // 自增前置写法,表达式传递新值 5System.out.println(a);System.out.print(b);
输出:
45
代码清单 5直观的展示了前置自增以及后置自增在作为表达式时的区别,前置自增传递的时自增后的“新值”(即第 9 行b=++j,++j从4变5后的5),后置自增传递的是自增前的“旧值”(即第 8 行a=i++,i++从4变5前的4)。同样的,前置自减与后置自减的区别也在于此。
自增与自减在 Java 编程中的使用频率会非常的高,请一定要弄清楚他们的特性,从而能更加准确高效的编写程序以及阅读程序。
整钱兑零任务背景
设有以下货币单位,从大到小依次为:
- dollar (1 美元,相当于 100 美分);
- quarter (25 美分);
- dime (10 美分);
- nickel (5 美分);
- penny (1 美分)。
当输入了一个以美元为单位的金额时,需要将其兑换成以上货币单位的零钱,例如,0.5 dollar 可以兑换为 2 quarter 或者 5 dime。在本任务中,需要优先兑换大单位货币。即 0.5 dollar 应该兑换为 2 quarter 而不是其他单位的货币,只有在无法兑换更多当前单位的货币时,才考虑兑换小一级单位的货币。这样能够保证兑换唯一性。例如: 11.56 dollar 可以进行如下兑换:
- 11 dollar;
- 2 quarter;
- 0 dime;
- 1 nickel;
- 1 penny。
这是本任务中唯一正确的兑换结果,其他结果都不正确。
编程要求
根据提示,在右侧编辑器 Begin-End 区域补充代码,实现整钱兑零功能。具体要求如下:
-
变量
money是一个int类型的数,个位十位代表小数点后的部分,例如1156代表 11.56 美元。 -
输出兑换零钱的结果,样式详见测试说明的测试输出。
测试说明
平台会对你编写的代码进行测试:
测试输入:1156; 预期输出:
11 dollar2 quarter0 dime1 nickel1 penny
提示:
- 输出最后一行
penny后不换行 - 以下代码展示了一个输出示例:
/** 代码清单 6 */int a = 1;int b = 2;System.out.println(a + " nickel");System.out.print(b + " penny");
1 nickel2 penny
代码如下:
package step1;
import java.util.Scanner;
public class Main
{
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
int money = input.nextInt();
input.close();
//请在指定位置填写代码。
/********* Begin *********/
int dollar=money/100;
System.out.println(dollar+" dollar");
money%=100;
int quarter=money/25;
System.out.println(quarter+" quarter");
money%=25;
int dime=money/10;
System.out.println(dime+" dime");
money%=10;
int nickel=money/5;
System.out.println(nickel+" nickel");
money%=5;
int penny=money/1;
System.out.print(penny+" penny");
/********* End *********/
}
}
第2关:整钱兑零(改)
任务描述
本关任务:学习类型转换相关知识,并在第一关的整钱兑零任务基础上,完成修改输入要求的任务。
相关知识
为了完成本关任务,你需要了解并学习:
- 整钱兑零的输入问题;
- 数值类型转换;
- 类型转换带来的问题。
整钱兑零的输入问题
细心的你应该会发现,第一关的整钱兑零任务中,要求输入的是int类型的整型数据,即用1156代表实际的 11.56 美元。为何不用double或者float这样的浮点型数据作为输入呢,输入11.56不是跟实际情况更相符吗?
如果你完成了第一关的任务,应该明白解决问题的关键操作就是“整数除”(/)“取余”操作(%),例如如下代码:
/** 代码清单 1 */int money = 1156;// 取出了 dollar 单位的部分int dollar = money/100;// 取出了不足 1 dollar 的剩余其他单位部分money = money%100;
代码清单 1提供了一种解决整钱兑零任务的常规思路,你可以尝试将代码清单 1中的int类型替换为double类型,此时就会出现类型不对应导致的操作上的问题。例如如下代码:
/** 代码清单 2 */double money = 11.56;// 这是有语法错误的赋值语句,不能将 double 类型赋值给 int 类型int dollar = money*100/100;// 这是错误的表达式,不能对 double 类型使用 % 操作符。money = money%1;
代码清单 2中的错误代码,就是为什么第一关任务中使用整型作为输入的原因。 那么,这个任务就无法接受浮点类型作为输入了吗?
当然不是,Java 提供了强制类型转换,可以帮助我们解决这个问题,从而使得第一关的整钱对零任务可以接受浮点输入。
数值类型转换
其实,我们编写的程序可能会在不经意将发生数值类型转换,例如3 + 4.5。当一个二元操作符(例如+)的操作数中一个是浮点型(1.5),一个是整型(3),Java 会自动的将整型转化为浮点型。这样,3 + 4.5就变成了3.0 + 4.5,表达式产生的结果自然也就是一个浮点型。
总是可以将一个数值赋值给支持更大数值范围类型的变量。例如可以直接将 long类型的值赋值给float类型的变量。但反过来则不能直接进行,而必须进行显式的类型转换。这其实很好理解,要把一个“大范围”的值赋值给“小范围”的变量,这里可能会有“超范围”的风险,这种风险需要由程序员自己来承担,Java 本身不“背锅”。而显示的类型转换也就是强制类型转换,即明知道风险还是要进行的类型转换。
强制类型转换的语法要求是将“目标类型”放置于括号()内,其后紧跟需要进行类型转换的变量名或值。
示例如下:
/** 代码清单 3 */double a = 12.01;// 将 float 类型的变量 a 中的值进行强制类型转换int b = (int)a;System.out.print(b);
输出:
12
当然强制类型转换的也可以是表达式,但需要注意执行顺序:
/** 代码清单 4 */double a = 12.1;// 先将变量 a 中值强制转换为 int 型,再 *10 。int b = (int)a*10;// 先将变量 a 中的值 * 10 ,再将结果强制转换为 int 型。int c = (int)(a*10);System.out.println(b);System.out.print(c);
输出:
120121
注意,强制类型转换不能转换变量的类型,以下代码是错误的:
/** 代码清单 5 */double a = 12.1;// 错误,以下语句不会改变变量 a 的类型。(int)a;
事实上,代码清单 5第 2 行的语句会报错,错误是期待boolean类型,得到的却是int类型。至于为什么会报这样的错误,你可以将它当作一个暂时的疑问,通过后续课程的学习,你将会解开这个疑问。
类型转换带来的问题
上一节提到,之所以强制类型转换必须要显式进行,是因为 Java 不承担这种类型转换可能会带来的“意外风险”。因此,在进行强制类型转换操作之前,我们一定要充分考虑这个操作是否会造成错误。
例如如下语句:
/** 代码清单 6 */short a = (short) 65536;System.out.print(a);
输出:
0
代码清单 6很好的为我们展示了“超范围”的风险,显然数值65536超出了short类型的表示范围,因此得到了“出乎意料”的结果0。这种情况是我们在编程中使用强制类型转换时需要充分考虑的到的,这样才能对这些“意外”进行合理的规避或是处理。
编程要求
根据提示,在右侧编辑器 Begin-End 区域补充代码,实现整钱兑零功能。具体要求如下:
- 变量
money是一个double类型的数,个位十位代表小数点后的部分,例如11.56代表 11.56 美元,小数点后只有两位。 - 输出兑换零钱的结果,样式详见测试说明的测试输出。
测试说明
平台会对你编写的代码进行测试:
测试输入:11.56; 预期输出:
11 dollar2 quarter0 dime1 nickel1 penny
提示:
- 输出最后一行
penny后不换行 - 以下代码展示了一个输出示例:
/** 代码清单 6 */int a = 1;int b = 2;System.out.println(a + " nickel");System.out.print(b + " penny");
1 nickel2 penny
代码如下:
package step2;
import java.util.Scanner;
public class Main
{
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
double money = input.nextDouble();
input.close();
//请在指定位置填写代码。
/********* Begin *********/
int moneyTrans=(int)(money*100);
int dollar=moneyTrans/100;
System.out.println(dollar+" dollar");
moneyTrans%=100;
int quarter=moneyTrans/25;
System.out.println(quarter+" quarter");
moneyTrans%=25;
int dime=moneyTrans/10;
System.out.println(dime+" dime");
moneyTrans%=10;
int nickel=moneyTrans/5;
System.out.println(nickel+" nickel");
moneyTrans%=5;
int penny=moneyTrans/1;
System.out.println(penny+" penny");
/********* End *********/
}
}
1870

被折叠的 条评论
为什么被折叠?



