3.1 循环
3.1.1 while和do-while循环
自动售票机
- 如何能不断地投币-出票?
package com.meteor.loop;
import java.util.Scanner;
public class SimpleTicketDispenser {
public static void main(String[] args) {
// 初始化
Scanner in = new Scanner(System.in);
int balance = 0;
// 读入投币金额
while (true) {
System.out.print("请投币:");
int amount = in.nextInt();
balance = balance + amount;
if (balance >= 10) {
// 打印车票
System.out.println("**********");
System.out.println("Java城际铁路专线");
System.out.println(" 无指定座位票 ");
System.out.println(" 票价:10元 ");
System.out.println("**********");
// 计算并打印找零
System.out.println("找零:" + (balance - 10));
balance = 0;
}
}
}
}
3.1.2 数数字的例子
- 程序要读入一个正整数,然后输出这个整数的位数
- 输入:352,输出:3
package com.meteor.loop;
import java.util.Scanner;
public class CountNumber {
public static void main(String[] args) {
// 初始化
Scanner in = new Scanner(System.in);
int number;
int count = 0;
number = in.nextInt();
while (number > 0) {
number /= 10;
count++;
}
System.out.println(count);
}
}
3.1.3 while循环
- 如果我们把while翻译作“当”,那么一个while循环的意思就当条件满足时,不断地重复循环体内的语句
- 循环执行之前判断是否继续循环,所以有可能循环一次也没有被执行
- 条件成立是循环继续的条件
分析程序的运行
- 看程序的运行结果
- 人脑模拟计算机的运行,在纸上列出所有的变量,随着程序的进展不断重新计算变量的值。当程序运行结束时,留在表格最下面的就是程序的最终结果
- 调试
- 在程序适当的地方插入输出来显示变量的内容
- 在while循环的最后把变量打印出来
System.out.println("number="+number+";count="+count);
- 在程序适当的地方插入断点,进行Debug调试
- 在程序适当的地方插入输出来显示变量的内容
验证
- 测试程序常使用边界数据,如有效范围两端的数据、特殊的倍数等
- 个位数
- 10
- 0
- 负数
3.1.4 do-while循环
- 上面的程序,我们发现当输入0时,输出数字的位数为0,这是错的,可以用do-while循环改正。
- 在进入循环的时候不做检查,而是在执行完一轮循环体的代码之后,再来检查循环的条件是否满足,如果满足则继续下一轮
package com.meteor.loop;
import java.util.Scanner;
public class CountNumber {
public static void main(String[] args) {
// 初始化
Scanner in = new Scanner(System.in);
int number;
int count = 0;
number = in.nextInt();
do {
number /= 10;
count++;
System.out.println("number=" + number + ";count=" + count);
} while (number > 0);
System.out.println(count);
}
}
- do-while循环和while循环很像,区别是在循环体执行结束的时候才来判断条件。也就是说,无论如何,循环都会执行至少一遍,然后再来判断条件。与while循环相同的是,条件满足时执行循环,条件不满足时结束循环。
3.2 for循环
3.2.1 for循环
阶乘
- n! = 1×2×3×4×…×n
- 写一个程序,让用户输入n,然后计算输出n!
- 变量:
- 读用户的输入需要一个int的n,然后计算的结果需要用一个变量保存,可以是int的factor,在计算中需要有一个变量不断地从1递增到n,那可以是int的i
package com.meteor.loop;
import java.util.Scanner;
public class factorial {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int i = 1;
int factor = 1;
/*while (i <= n) {
factor = factor * i;
i = i + 1;
}*/
for (i = 1; i <= n; i++) {
factor = factor * i;
}
System.out.println(factor);
}
}
算到20的阶乘这个程序就算不对了
- 原因是使用int存储factor的值
- int在计算机中占4个字节,一个字节8位
- 计算机使用二进制存储
- 1位可以表示2个数,0或者1,最大的数为2^1-1=1
- 2位就可以表示4个数00、01、10、11,分别对应十进制的0,1,2,3,最大的数为2^2-1=3
- int一共有32位,一共可以表示2^32=4294967296个数,其中拿出一位作为符号位,剩下31位,int可以表示的最大的整数为:2^31-1=2147483648-1=2147483647,int可以表示的最小的数为:-2^31=-2147483648
- 20的阶乘为:2432902008176640000>2147483647远远超过了int的范围
for循环像一个计数循环:设定一个计数器,初始化它,然后在计数器到达某值之前,重复执行循环体,而每执行一轮循环,计数器值以一定步进进行调整,比如加1或者减1
- 第一个部分是一个初始化,可以定义一个新的变量:int count=10或者直接赋值i=10
- 第二个部分是循环维持的条件。这个条件是先验的,与while循环一样,进入循环之前,首先要检验条件是否满足,条件满足才执行循环;条件不满足就结束循环。
- 第=个部分是步进,即每轮执行了循环体之后,必须执行的表达式。通常我们在这里改变循环变量,进行加或减的操作。
- for=对于
- for(;条件;) == while(条件)
循环次数
for ( i=0; i<n; i=i+1)
这个循环次数是n
Tips for loop
- 如果有固定次数,用for
- 如果必须执行一次,用do_while
- 其他情况用while
3.2.2 复合赋值
- 5个算术运算符,+-/%,可以和赋值运算符“=”结合起来,形成复合赋值运算符:“+=”、“-=”、“=”、“/=”和“%=”
- total += 5;
- total = total + 5;
- “++”和“–”是两个很特殊的运算符,它们是单目运算符,这个算子还必须是变量。这两个运算符分别叫做递增和递减运算符,他们的作用就是给这个变量+1或者-1
- count++;
- count += 1;
- count = count + 1;
- ++和–可以放在变量的前面,叫做前缀形式,也可以放在变量的后面,叫做后缀形式
- a++的值是a加1以前的值,而++a的值是加了1以后的值,无论哪个,a自己的值都加了1
3.3 循环控制(含复合赋值、逻辑类型)
3.3.1 循环控制
素数
- 只能被1和自己整除的数,不包括1
- ·2,3,5,7,11,13,17,19
package com.meteor.loop;
import java.util.Scanner;
public class Prime {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int isPrime = 1;
for (int i = 2; i < n; i++) {
if (n % i == 0) {
isPrime = 0;
System.out.println(n + "不是素数,i="+i);
}
}
if (isPrime == 1) {
System.out.println(n + "是素数");
}
// 14
// 14不是素数,i=2
// 14不是素数,i=7
// 14不是素数
}
}
- 上面的程序如果一个数如14不是素数,会输出多次,实际上只需要输出一次,可以用break来跳出循环
package com.meteor.loop;
import java.util.Scanner;
public class Prime {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int isPrime = 1;
for (int i = 2; i < n; i++) {
if (n % i == 0) {
isPrime = 0;
System.out.println(n + "不是素数,i="+i);
break;
}
}
if (isPrime == 1) {
System.out.println(n + "是素数");
}
// 14
// 14不是素数,i=2
}
}
- break:跳出循环
- continue:跳过循环这一轮,剩下的语句进入下一轮
3.3.2 多重循环
- 如何写程序输出100以内的素数?
package com.meteor.loop;
import java.util.Scanner;
public class Prime {
public static void main(String[] args) {
for (int n = 2; n < 100; n++) {
int isPrime = 1;
for (int i = 2; i < n; i++) {
if (n % i == 0) {
isPrime = 0;
break;
}
}
if (isPrime == 1) {
System.out.print(n + " ");
}
//2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
}
}
}
- 九九乘法表
package com.meteor.loop;
public class Multi {
public static void main(String[] args) {
for (int i = 1; i <= 9; i++)
{
for (int j = 1; j <= 9; j++)
{
System.out.println("\t"+(i * j));
}
System.out.println();
}
}
}
- 如何写程序输出前50个素数。不知道准确的循环次数。
/**
* 前50个素数
*/
private static void primeCount() {
int count = 0;
int n = 2;
while (count < 50) {
int isPrime = 1;
for (int i = 2; i < n; i++) {
if (n % i == 0) {
isPrime = 0;
break;
}
}
if (isPrime == 1) {
count++;
System.out.print(n + " ");
}
n++;
}
}
- 凑钱数,如何用1元、5元、10元和20元的凑出输入的金额呢?
package com.meteor.loop;
import java.util.Scanner;
public class Coin {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int amount = in.nextInt();
for (int one = 0; one <= amount; one++) {
for (int five = 0; five <= amount / 5; five++) {
for (int ten = 0; ten <= amount / 10; ten++) {
for (int twenty = 0; twenty <= amount / 20; twenty++) {
if (one + 5 * five + 10 * ten + 20 * twenty == amount) {
System.out.println(one + "张1元," + five + "张5元," + ten + "张10元," + twenty + "张20元->" + amount);
}
}
}
}
}
}
}
- 现在只要有一个结果,程序就停止,如何跳出多重循环呢?
- 在循环前可以放一个标号来标示循环:
- label:
- 带标号的break和continue对那个循环起作用
package com.meteor.loop;
import java.util.Scanner;
public class Coin {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int amount = in.nextInt();
OUT://标号
for (int one = 0; one <= amount; one++) {
for (int five = 0; five <= amount / 5; five++) {
for (int ten = 0; ten <= amount / 10; ten++) {
for (int twenty = 0; twenty <= amount / 20; twenty++) {
if (one + 5 * five + 10 * ten + 20 * twenty == amount) {
System.out.println(one + "张1元," + five + "张5元," + ten + "张10元," + twenty + "张20元->" + amount);
break OUT;
}
}
}
}
}
}
}
3.3.3 逻辑类型与逻辑运算
逻辑类型
- 关系运算的结果是一个逻辑值,true或false。这个值可以保存在一个对应的逻辑类型的变量中,这样的变量类型是boolean
- 布尔(Boolean)是为了纪念George Boole对逻辑计算的贡献
- boolean flag = true;
- boolean done = false;
逻辑运算
- 逻辑运算是对逻辑量进行的运算,只有逻辑量可以参与运算
- 逻辑非:
!
- 逻辑与:
&&
- 逻辑或:
||
- 逻辑非:
优先级
3.4 循环应用
3.4.1 平均数
- 让用户输入一系列的正整数,最后输入-1表示输入结束,然后程序计算出这些数字的平均数,输出输入的数字的个数和平均数
package com.meteor.loop;
import java.util.Scanner;
public class Avg {
public static void main(String[] args) {
int number;
int sum = 0;
int count = 0;
Scanner in = new Scanner(System.in);
/* number = in.nextInt();
while (number != -1) {
sum += number;
count++;
number = in.nextInt();
}*/
do {
number = in.nextInt();
if (number != -1) {
sum = sum + number;
count++;
}
} while (number != -1);
if (count > 0) {
System.out.println("平均数=" + (double)sum / count);
}
}
}
3.4.2 猜数游戏
-让计算机来想一个数,然后让用户来猜,用户每输入一个数,就告诉它是大了还是小了,直到用户猜中为止,最后还要告诉用户它猜了多少次。
package com.meteor.loop;
import java.util.Scanner;
public class GuessNumber {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int number = (int) (Math.random()*100+1);
int a;
int count = 0;
do {
a = in.nextInt();
count++;
if (a > number) {
System.out.println("偏大");
} else if (a < number) {
System.out.println("偏小");
}
} while(a!=number);
System.out.println("恭喜你猜对了,你猜了" + count + "次");
}
}
3.4.3 整数分解
- 一不数是由1至多位数字组成的,如何分解出整数的各个位上的数字,然后实现数的逆序
package com.meteor.loop;
import java.util.Scanner;
public class InvertedSequence {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int number;
number = in.nextInt();
int result = 0;
do {
int digit = number % 10;
number = number / 10;
result = result * 10 + digit;
} while (number > 0);
System.out.println(result);
}
}
3.4.4 求最大公约数
package com.meteor.loop;
import java.util.Scanner;
public class GreatestCommonDivisor {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int a = in.nextInt();
int b = in.nextInt();
int oa = a;
int ob = b;
while (b != 0) {
int r = a % b;
System.out.println(a + "," + b + "," + r);
a = b;
b = r;
}
System.out.println(oa + "和" + ob + "的最大公约数是" + a);
}
}