计算机的智能是建筑在规则的基础上的,在遇到情况的时候,根据事先制定的规则做出判断,是计算机最基本的能力。
能做判断的基础,是能对数据做比较,比较就是关于两个数据是否相等、谁大谁小的结论,这需要用到关系运算:对两个数据之间的关系的计算。
Java提供了六个关系运算符:
== 相等
!= 不相等
> 大于
>= 大于或等于
< 小于
<= 小于或等于
注意其中有两个字符的运算符:==、>=和<=的两个字符必须紧紧连在一起,中间不能插入空格。
关系运算的结果是一个逻辑值。
逻辑值只有两种可能的值:true(真,表示成立)或false(假,表示不成立)。
当两个值的关系符合关系运算符的预期时,关系运算的结果为true,否则为false。
2.1 比较
案例:自动售票机工作机制
工作原理:
用户:选择线路 & 投入纸币
自动售票机:打印车票 & 返回找零或者是告知用户余额不足
即:计算机读取用户的两个输入,进行计算判断,输出结果。
首先对该案例进行简化分析:
如果规定当前自动售票机只贩卖一种票价的票,应该怎么实现上述工作机制的程序呢?
代码 1(含成功和失败两种结果)
import java.util.Scanner;
public class Hello {
public static void main(String[] args) {
// 初始化
Scanner in = new Scanner(System.in);
// 读入投币金额
System.out.print("请投币:");
int amount=in.nextInt();
// 打印车票
System.out.println("*************");
System.out.println("*Java城际铁路专线*");
System.out.println("* 无指定座位票 *");
System.out.println("* 票价:10元 *");
System.out.println("****************");
// 计算并打印找零
System.out.println("找零:"+(amount-10));
}
}
运行结果 1(输入>=10元的数值)
请投币:10
*************
*Java城际铁路专线*
* 无指定座位票 *
* 票价:10元 *
****************
找零:0
运行结果 2(输入<10元的数值)
请投币:5
*************
*Java城际铁路专线*
* 无指定座位票 *
* 票价:10元 *
****************
找零:-5
根据上述代码运行结果 2,我们发现当用户输入的数值<10的时候,找零变成了负数,同时在工作机制上,此时也是出票的,这并不符合常理。因此这个程序还需要写入一个判断的功能代码。
改进代码:(增加判断功能代码)
import java.util.Scanner;
public class Hello {
public static void main(String[] args) {
// 初始化
Scanner in = new Scanner(System.in);
// 读入投币金额
System.out.print("请投币:");
int amount=in.nextInt();
System.out.println(amount);
System.out.println(amount>=10);//进行输入值的与10的大小判断
// 打印车票
System.out.println("*************");
System.out.println("*Java城际铁路专线*");
System.out.println("* 无指定座位票 *");
System.out.println("* 票价:10元 *");
System.out.println("****************");
// 计算并打印找零
System.out.println("找零:"+(amount-10));
}
}
运行结果 1(输入>10的数,判断为真true)
请投币:15
15
true
*************
*Java城际铁路专线*
* 无指定座位票 *
* 票价:10元 *
****************
找零:5
运行结果 2(输入<10的数,判断为假false)
请投币:3
3
false
*************
*Java城际铁路专线*
* 无指定座位票 *
* 票价:10元 *
****************
找零:-7
关系优先级问题
所有的算术优先级均高于关系优先级。
举例:7>=3+2 在这个式子里面,优先做3+2,然后才做>= 。
==和!=的优先级比其他的低,同级的连续关系运算从左到右计算。
注意:true和false不能比较大小!!
判断两个浮点数(double)大小关系:
错误代码演示:
import java.util.Scanner;
public class Hello {
public static void main(String[] args) {
double a=1.0;
double b=0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1;
System.out.println(a==b);
System.out.println("a="+a+";"+"b="+b);
}
}
运行结果:
false
a=1.0;b=0.9999999999999999
在数学上,1等于10个0.1相加,这个在计算机程序中却不是这样的。因为是浮点数,而这段代码也体现了第一周中所讲浮点数计算结果精度不如整数计算精度。
因此,引入改进方案,使用a和b的差的绝对值是否小于一个比较小的数1*10的-6次方。
公式:Math.abs(f1-f2)<0.00001
改进代码:
import java.util.Scanner;
public class Hello {
public static void main(String[] args) {
double a=1.0;
double b=0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1;
System.out.println(a==b);
System.out.println("a="+a+";"+"b="+b);
System.out.println(Math.abs(a-b)<1e-6);
}
}
运行结果:
false
a=1.0;b=0.9999999999999999
true
根据上述运行结果,通过使用绝对值的方法后1等于10个0.1了,为true。
2.2 判断
接着上面自动售票机的案例,我们要实现如果输入票价大于10,那么就出票,否则不出票。
代码:
import java.util.Scanner;
public class Hello {
public static void main(String[] args) {
// 初始化
Scanner in = new Scanner(System.in);
// 读入投币金额
System.out.print("请投币:");
int amount=in.nextInt();
System.out.println(amount);
System.out.println(amount>=10);//进行输入值的与10的大小判断
if(amount>10) {
// 打印车票
System.out.println("*************");
System.out.println("*Java城际铁路专线*");
System.out.println("* 无指定座位票 *");
System.out.println("* 票价:10元 *");
System.out.println("****************");
// 计算并打印找零
System.out.println("找零:"+(amount-10));}
}
}
运行结果 1(输入值>10,出票并找零)
请投币:90
90
true
*************
*Java城际铁路专线*
* 无指定座位票 *
* 票价:10元 *
****************
找零:80
运行结果 2(输入值<10,返回false不出票不找零)
请投币:4
4
false
学会使用Debug调试,在eclipse的左上角切换debug模式和Java模式。
使用判断语句进行相关代码操练
代码 1:(与常量作比较进行语句判断输出结果)
import java.util.Scanner;
public class Age {
public static void main(String[] args) {
final int MINOR=35;
System.out.print("请输入你的年龄:");
Scanner in=new Scanner(System.in);
int age=in.nextInt();
System.out.print("你的年龄是:"+age);
if(age<MINOR)
{
System.out.println("年轻是美好的!");
}
System.out.println("年龄决定了你的精神世界,好好努力吧!");
}
}
运行结果 1(年龄小于设定值)
请输入你的年龄:19
你的年龄是:19年轻是美好的!
年龄决定了你的精神世界,好好努力吧!
运行结果 2(年龄大于设定值,不满足if语句运行条件)
请输入你的年龄:55
你的年龄是:55年龄决定了你的精神世界,好好努力吧!
根据上述两种运行结果,可以明显看出if语句的妙处:
不满足if语句运行条件的就不执行if内的程序。
代码 2:(比较两个数的大小)
首先下面这段代码报错了,原因:比较x和y的大小if判断语句中只体现了对x为较大一方的看法,而没有顾及y的角度,至此导致程序报错,无法进行。
import java.util.Scanner;
public class Age {
public static void main(String[] args) {
Scanner in=new Scanner(System.in);
int x=in.nextInt();
int y=in.nextInt();
int max;
if(x>y)
max=x;
System.out.println(max);
}
}
因此,我们要对上述代码进行改进。
改进代码 1(使用两个if判断语句)
import java.util.Scanner;
public class Age {
public static void main(String[] args) {
Scanner in=new Scanner(System.in);
int x=in.nextInt();
int y=in.nextInt();
int max;
if(x>y)
{
max=x;
System.out.println(max);
}
if(y>x)
{
max=y;
System.out.println(max);
}
}
}
运行结果:
2(输入x的值)
15(输入y的值)
15(程序输出的值)
改进代码 2(最优解决,使用if else语句)
import java.util.Scanner;
public class Age {
public static void main(String[] args) {
Scanner in=new Scanner(System.in);
int x=in.nextInt();
int y=in.nextInt();
int max;
if(x>y)
max=x;
else
max=y;
System.out.println(max);
}
}
运行结果:
3(输入x的值)
77(输入y的值)
77(程序输出的值)
2.3 分支
根据上一版块比较两个数的大小,现在延伸到比较三个数的大小。
有x,y,z三个变量,怎么进行比较呢?
方法:可以两两先比较,比较出来大的一方再与第三个变量进行比较。
因此代码书写如下:(采用“嵌套”思想)
import java.util.Scanner;
public class Age {
public static void main(String[] args) {
Scanner in=new Scanner(System.in);
int x=in.nextInt();
int y=in.nextInt();
int z=in.nextInt();
int max;
if(x>y)
max=x;
{
if(x>z)
max=x;
else
max=z;
}
if(y>x)
max=y;
{
if(y>z)
max=y;
else
max=z;
}
System.out.println(max);
}
}
运行结果:
66 3 99(输入三个数)
99(输出)
举例代码:(分段函数的表示,使用级联的if,else if,else)
import java.util.Scanner;
public class Age {
public static void main(String[] args) {
Scanner in=new Scanner(System.in);
int x=in.nextInt();
int f;
if(x<0) {
f=-1;
}
else if(x==0) {
f=0;
}
else {
f=2*x;
}
System.out.println(f);
}
}
代码解释:
当x<0时,f(x)=-1;
当x=0时,f(x)=0;
当x>0时,f(x)=2*x
运行结果:
3
6
使用switch-case代替多级联的if-else if 语句
格式:
switch(控制表达式){
case 常量:
语句
……
case 常量:
语句
……
default:
语句
……
}
解释:
①控制表达式只能是整数型的结果
②常量可以是常数,也可为常数计算的表达式
③根据表达式结果,寻找匹配的case,并执行case后面的语句直到break为止
④如果所有case都不匹配,就执行default后面的语句;若没有default,就什么都不做
代码演示:
import java.util.Scanner;
public class Age {
public static void main(String[] args) {
Scanner in=new Scanner(System.in);
int type=in.nextInt();
switch(type)
{
case 1:
case 2:
System.out.println("你好");
break;
case 3:
System.out.println("晚上好");
case 4:
System.out.println("再见");
default:
System.out.println("你说啥呢?我听不懂!");
break;
}
}
}
运行结果:
3
晚上好
再见
你说啥呢?我听不懂!
解释:运行switch-case,遇到break才终止程序,否则继续执行到结束。
**第二周编程作业**(2题)
1 时间换算(5分)
题目内容:
UTC是世界协调时,BJT是北京时间,UTC时间相当于BJT减去8。现在,你的程序要读入一个整数,表示BJT的时和分。整数的个位和十位表示分,百位和千位表示小时。如果小时小于10,则没有千位部分;如果小时是0,则没有百位部分;如果分小于10分,需要保留十位上的0。如1124表示11点24分,而905表示9点5分,36表示0点36分,7表示0点7分。
有效的输入范围是0到2359,即你的程序不可能从测试服务器读到0到2359以外的输入数据。
你的程序要输出这个时间对应的UTC时间,输出的格式和输入的相同,即输出一个整数,表示UTC的时和分。整数的个位和十位表示分,百位和千位表示小时。如果小时小于10,则没有千位部分;如果小时是0,则没有百位部分;如果分小于10分,需要保留十位上的0。
提醒:要小心跨日的换算。
输入格式:
一个整数,表示BJT的时和分。整数的个位和十位表示分,百位和千位表示小时。如果小时小于10,则没有千位部分;如果小时是0,则没有百位部分;如果小时不是0而且分小于10分,需要保留十位上的0。
输出格式:
一个整数,表示UTC的时和分。整数的个位和十位表示分,百位和千位表示小时。如果小时小于10,则没有千位部分;如果小时是0,则没有百位部分;如果小时不是0而且分小于10分,需要保留十位上的0。
输入样例:
933
输出样例:
133
代码:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
// TODO 自动生成的方法存根
Scanner in=new Scanner(System.in);
int BJT;
int UTC;
BJT=in.nextInt();
if(BJT>=0 && BJT<=2359) //数据范围
{
if(BJT%100<=60) //分钟范围
{
if(BJT/100>=8)
{
UTC=(BJT/100-8)*100+BJT%100;
System.out.println(UTC);
}
else
{//跨日计算
UTC=(24-8+BJT/100)*100+BJT%100;
System.out.println(UTC);
}
}
else
{
System.out.println("分钟位(十位和个位)超出时间范围!");
}
}
else
{
System.out.println("数据错误!有效的输入范围是0到2359!");
}
in.close();
}
}
2 信号报告(5分)
题目内容:
无线电台的RS制信号报告是由三两个部分组成的:
R(Readability) 信号可辨度即清晰度.
S(Strength) 信号强度即大小.
其中R位于报告第一位,共分5级,用1—5数字表示.
1---Unreadable
2---Barely readable, occasional words distinguishable
3---Readable with considerable difficulty
4---Readable with practically no difficulty
5---Perfectly readable
报告第二位是S,共分九个级别,用1—9中的一位数字表示
1---Faint signals, barely perceptible
2---Very weak signals
3---Weak signals
4---Fair signals
5---Fairly good signals
6---Good signals
7---Moderately strong signals
8---Strong signals
9---Extremely strong signals
现在,你的程序要读入一个信号报告的数字,然后输出对应的含义。如读到59,则输出:
Extremely strong signals, perfectly readable.
输入格式:
一个整数,信号报告。整数的十位部分表示可辨度,个位部分表示强度。输入的整数范围是[11,59]内有效的数字,这个范围外的数字不可能出现在测试数据中。
输出格式:
一句话,表示这个信号报告的意义。按照题目中的文字,先输出表示强度的文字,跟上逗号和空格,然后是表示可辨度的文字,跟上句号。注意可辨度的句子的第一个字母是小写的。注意这里的标点符号都是英文的。
输入样例:
33
输出样例:
Weak signals, readable with considerable difficulty.
时间限制:500ms 内存限制:32000kb
代码:
import java.util.Scanner;
public class Main{
public static void main(String[] args) {
// 初始化
Scanner in = new Scanner(System.in);
int RS = in.nextInt();
while (RS >= 11 && RS <= 59) {
int r = RS % 10;
int s = RS / 10;
switch (r)
{
case 1:
System.out.print("Faint signals, barely perceptible");
break;
case 2:
System.out.print("Very weak signals");
break;
case 3:
System.out.print("Weak signals");
break;
case 4:
System.out.print("Fair signals");
break;
case 5:
System.out.print("Fairly good signals");
break;
case 6:
System.out.print("Good signals");
break;
case 7:
System.out.print("Moderately strong signals");
break;
case 8:
System.out.print("Strong signals");
break;
case 9:
System.out.print("Extremely strong signals");
break;
}
switch (s)
{
case 1:
System.out.print(", unreadable.");
break;
case 2:
System.out.print(", barely readable, occasional words distinguishable.");
break;
case 3:
System.out.print(", readable with considerable difficulty.");
break;
case 4:
System.out.print(", readable with practically no difficulty.");
break;
case 5:
System.out.print(", perfectly readable.");
break;
}
break;
}
in.close();
}
}