目录
和C语言类似地, Java的程序逻辑控制也分为 顺序结构, 分支结构, 循环结构.
1. 顺序结构
顺序结构即 按照代码书写的顺序一行一行执行.
System.out.println("aaa");
System.out.println("bbb");
System.out.println("ccc");
运行结果:
aaa
bbb
ccc
如果调整代码的书写顺序, 则执行顺序也发生变化.
System.out.println("aaa");
System.out.println("ccc");
System.out.println("bbb");
运行结果:
aaa
ccc
bbb
2. 分支结构
2.1 if 语句
2.1.1 语法格式1
if (布尔表达式) {
// 语句
}
如果布尔表达式结果为true,执行if中的语句,否则不执行。
2.1.2 语法格式2
if (布尔表达式) {
// 语句1
} else {
// 语句2
}
如果布尔表达式结果为true,则执行if中语句,否则执行else中语句。
2.1.3 语法格式3
if (布尔表达式1) {
// 语句1
} else if(布尔表达式2) {
// 语句2
} else {
// 语句3
}
表达式1成立,执行语句1,否则表达式2成立,执行语句2,否则执行语句3.
2.2 switch 语句
在C语言中也有了解过switch的有关语法, 那么在Java中switch的使用也是几乎一样的.
int a = 2;
switch (a) {
case 2:
System.out.println("two");
break;
case 1:
System.out.println("one");
break;
default:
System.out.println("没有匹配!");
break;
}
执行流程:
1. 先计算switch后()
中表达式的值
2. 和case依次比较,一旦有响应的匹配就执行该项下的语句,直到遇到break时结束
3. 当表达式的值没有与所列项匹配时,执行default
【注意事项】
- 多个case后的常量值不可以重复
- switch的括号内只能是以下类型的表达式:
- 基本类型:byte、char、short、int,注意不能是long类型
- 引用类型:String常量串、枚举类型
- 不可以是long, float, double, boolean
- break 不要遗漏, 否则会失去 "多分支选择" 的效果
int day = 1;
switch(day) {
case 1:
System.out.println("星期一");
// break;
case 2:
System.out.println("星期二");
break;
}
运行结果:
星期一
星期二
- switch 不能表达复杂的条件
// 例如: 如果 num 的值在 10 到 20 之间, 就打印 hehe
// 这样的代码使用 if 很容易表达, 但是使用 switch 就无法表示.
if (num > 10 && num < 20) {
System.out.println("hehe");
}
- switch 虽然支持嵌套, 但是很丑,一般不推荐~
3. 循环结构
Java中的循环结构和C语言一样, 也是三个.
for, while, do while.
从使用频率上, while会比for循环使用的更多一点.
3.1 while循环
//语法格式:
while(布尔表达式){
//..
}
// 打印1-10之间的所有数字, 并求和
int i = 1;
int sum = 0;
while (i <= 10) {
sum += i;
i++;
}
System.out.println(sum);
//1-100的和
//1-100的奇数和
//1-100的偶数和
int i = 1;
int sum = 0;
int sumOdd = 0;
int sumEve = 0;
while (i <= 100) {
if (i % 2 == 0) {
sumEve += i;
} else {
sumOdd += i;
}
sum += i;
i++;
}
System.out.println(sum);
System.out.println(sumOdd);
System.out.println(sumEve);
//计算5的阶乘
int i = 1;
int ret = 1;
while (i <= 5) {
ret *= i;
i++;
}
System.out.println(ret);
//计算 1! + 2! + 3! + 4! + 5!
int ret2 = 0;
int n = 1;
while (n <= 5) {
int i = 1;
int ret = 1;
while (i <= n) {
ret *= i;
i++;
}
ret2 += ret;
n++;
}
System.out.println(ret2);
//死循环
int a = 1;
while (true) {
System.out.println("fasfa");
}
3.2 break与continue
break: 直接跳出循环, 即结束循环.
continue: 结束 本趟循环.
//找到1-100之间
//既能被3整除, 又能被5整除的所有数字.
int i = 1;
while (i <= 100) {
if (i % 15 != 0) {
i++;
continue;
}
System.out.println(i);
i++;
}
3.3 for循环
//基本语法
for(表达式①;布尔表达式②;表达式③){
表达式④;
}
- 表达式1: 用于初始化循环变量初始值设置,在循环最开始时执行,且只执行一次
- 表达式2: 循环条件,满则循环继续,否则循环结束
- 表达式3: 循环变量更新方式
//1. 打印 1 - 10 的数字
for (int i = 1; i <= 10; i++) {
System.out.println(i);
}
//2. 计算 1 - 100 的和
int sum = 0;
for (int i = 1; i <= 100; i++) {
sum += i;
}
System.out.println("sum = " + sum);
执行结果:
5050
//3. 计算 5 的阶乘
int result = 1;
for (int i = 1; i <= 5; i++) {
result *= i;
}
System.out.println("result = " + result);
//4. 计算 1! + 2! + 3! + 4! + 5!
int sum = 0;
for (int i = 1; i <= 5; i++) {
int tmp = 1;
for (int j = 1; j <= i; j++) {
tmp *= j;
}
sum += tmp;
}
System.out.println("sum = " + sum);
4. 输入输出
接下来我们来介绍一下Java中的输入输出.
这一部分并不算特别重要, 但是在后续写代码的过程中有可能会用到.
4.1 输出到控制台
有三种方式:
System.out.println(msg); // 输出一个字符串, 带换行
System.out.print(msg); // 输出一个字符串, 不带换行
System.out.printf(format, msg); // 格式化输出
println
输出的内容自带 \n,print
不带 \nprintf
的格式化输出方式和 C 语言的printf
是基本一致的.
格式化字符串
转换符 | 类型 | 举例 | |
---|---|---|---|
d | 十进制整数 | ("%d", 100) | 100 |
x | 十六进制整数 | ("%x", 100) | 64 |
o | 八进制整数 | ("%o", 100) | 144 |
f | 定点浮点数 | ("%f", 100f) | 100.000000 |
e | 指数浮点数 | ("%e", 100f) | 1.000000e+02 |
g | 通用浮点数 | ("%g", 100f) | 100.000 |
a | 十六进制浮点数 | ("%a", 100) | 0x1.9p6 |
s | 字符串 | ("%s", 100) | 100 |
c | 字符 | ("%c", ‘1’) | 1 |
b | 布尔值 | ("%b", 100) | true |
h | 散列码 | ("%h", 100) | 64 |
% | 百分号 | ("%.2f%%", 2/7f) | 0.29% |
4.2 从键盘输入
在我们找工作的笔试过程中经常会需要我们自己来处理输入输出.
Java中的输入需要工具类Scanner, 也就是要导入util包java.util.Scanner
import java.util.Scanner; // 需要导入 util 包
类比代码int a = 10;
通过类型定义变量.
Scanner scan = new Scanner(System.in);
System.in
意为从键盘获取输入值.
那么接下来我们就可以通过scan
这个变量通过.
找到这里面要用的方法.
//比如
int age = sc.nextInt();
此时代码执行就会要求读一个整数.
完整代码如下:
public class Test {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("输入你的年龄:");
int age = scan.nextInt();
System.out.println("年龄:" + age);
sc.close(); // 注意, 要记得调用关闭方法
}
}
使用 Scanner 循环读取 N 个数字,并求取其平均值
Scanner sc = new Scanner(System.in);
int sum = 0;
int num = 0;
while (sc.hasNextInt()) {
int tmp = sc.nextInt();
sum += tmp;
num++;
}
System.out.println("sum = " + sum);
System.out.println("avg = " + sum / num);
sc.close();
执行结果:
10
40.0
50.5
^Z
sum = 150.5
avg = 30.1
注意事项: 当循环输入多个数据的时候, 使用 ctrl + z 来结束输入 (Windows 上使用 ctrl + z, Linux / Mac 上使用 ctrl+ d).
5. 练习
1. 求一个整数,在内存当中存储时,二进制1的个数。
让该整数的每一位和1进行按位与操作, 而要让每一位都能和1按位与, 只需使用右移操作符即可.
int n = -1;
int count = 0;
for (int i = 0; i < 32; i++) {
if (((n >> i) & 1) != 0) {
count++;
}
}
System.out.println(count);
注意: 按照以上代码完成题目, 会有一个小问题.
不管是什么数字, 都得移动31次.
从这个角度来看, 是没有必要的. 比如判断数字1它本身的二进制位1的个数, 在第一位按位与, 接下来右移之后, 会发现后面的都是0了, 就多了很多不必要的操作.
所以就有了第二种写法.
int n = -1;
int count = 0;
while (n != 0) {
if ((n & 1) != 0) {
count++;
}
n = n >>> 1;
}
System.out.println(count);
接下来还有一个在算法层次的对代码的优化.
int n = -1;
int count = 0;
while (n != 0) {
n = n & (n - 1);//每次 & 时都会让二进制位少一个1
count++;
}
System.out.println(count);
2. 计算1/1-1/2+1/3-1/4+1/5 …… + 1/99 - 1/100 的值
1. 从上述表达式可以分析出: 该表达式主要由100项,基数项为正,偶数项为负
2. 设置一个循环从1~100,给出表达式中的每一项:1.0/i { 注意此处不能使用1,否则结果全部为0 }
然后使用flag标记控制奇偶项,奇数项为正,偶数项为负
然后将所有的项相加即可
double sum = 0.0;
int flg = 1;
for (int i = 1; i <= 100; i++) {
sum = sum + 1.0 / i * flg;
flg = -flg;
}
System.out.println(sum);
3. 水仙花数: 求出0~999之间的所有“水仙花数”并输出。(“水仙花数”是指一个三位数,其各位数字的立方和确好等于该数本身,如: 153=1^3+5^3+3^3 ,则153是一个“水仙花数”。)
public static void main(String[] args) {
for (int i = 1; i <= 999999; i++) {
// 1. 算是几位数 -> 使用 count 存储
int count = 0;
int tmp = i; // 为了求 i 是几位数, 所以让 tmp 来辅助求位数, 而不用 i
int sum = 0;
while (tmp != 0) {
tmp /= 10;
count++;
}
//count里面就存储了当前数字i是几位数
// 2. 求每一位数字是几
// 3. 把每一位数字是几, 位数的次幂算出来, 求和
tmp = i;
while (tmp != 0) {
sum += Math.pow(tmp % 10, count);
tmp /= 10;
}
//sum就存储了和
if (sum == i) {
System.out.println(i);
}
}
}
4. 打印 X 图形
多组输入,一个整数(2~20),表示输出的行数,也表示组成“X”的反斜线和正斜线的长度。针对每行输入,输出用“*”组成的X形图案。
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
while(scan.hasNextInt()) {
int n = scan.nextInt();
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
if ((i == j) || (i + j == n - 1)) {
System.out.print("*");
} else {
System.out.print(" ");
}
}
System.out.println();
}
}
}
}
5. 乘法口诀表: 输出n*n的乘法口诀表,n由用户输入。
for (int i = 1; i <= 9; i++) {
for (int j = 1; j <= i; j++) {
System.out.print(i + "*" + j + "=" + i * j + " ");
}
System.out.println();
}
6. 输出一个整数的每一位,如:123的每一位是3,2,1
int n = 123;
while (n != 0) {
System.out.println(n % 10);
n /= 10;
}
7. 模拟登录: 编写代码模拟三次密码输入的场景。 最多能输入三次密码,密码正确,提示“登录成功”,密码错误, 可以重新输入,最多输入三次。三次均错,则提示退出程序
Scanner scanner = new Scanner(System.in);
int count = 3;
while (count != 0) {
System.out.println("请输入你的密码,共有" + count + "次机会!");
String pass = scanner.nextLine();
//if(pass == "123") {//equals
if (pass.equals("123")) {//equals
System.out.println("登录成功!");
break;
} else {
System.out.println("登录失败!");
}
count--;
}
8. 二进制序列: 获取一个数二进制序列中所有的偶数位和奇数位, 分别输出二进制序列.
int n = 7;
for (int i = 31; i >= 1; i -= 2) {
System.out.print(((n >> i) & 1) + " ");
}//偶数
System.out.println();
for (int i = 30; i >= 0; i -= 2) {
System.out.print(((n >> i) & 1) + " ");
}
9. 判定一个数字是否是素数
int n = 9;
int i = 2;
for (; i < n; i++) {
if (n % i == 0) {
System.out.println("不是素数!");
break;
}
}
if (i == n) {
System.out.println("是素数!");
}
一个大于 n/2 的因数必然会有一个小于或等于 n/2 的对应因数。这是因为这个因数可以表示为 n 的另一个因数和 n/2 的乘积,我们可以将 n 分为两个相等的部分,其中一部分是小于或等于 n/2 的因数的倍数
int n = 11;
int i = 2;
for (; i <= n / 2; i++) {
if (n % i == 0) {
System.out.println("不是素数!");
break;
}
}
if (i > n / 2) {
System.out.println("是素数!");
}
int n = 11;
int i = 2;
for (; i <= Math.sqrt(n); i++) {
if (n % i == 0) {
System.out.println("不是素数!");
break;
}
}
if (i > Math.sqrt(n)) {
System.out.println("是素数!");
}
10. 打印 1 - 100 之间所有的素数
for (int n = 1; n <= 100; n++) {
int i = 2;
for (; i <= Math.sqrt(n); i++) {
if (n % i == 0) {
break;
}
}
if (i > Math.sqrt(n)) {
System.out.println(n + "是素数!");
}
}