资源描述
实验2.3 循环程序设计
2.3.1 实验目的
(1) 掌握三种循环语句的使用,能分析循环的执行过程;
(2) 掌握break和continue语句的使用;
(3)了解如何利用求余和整除操作获取和删除一个整数的最低位;
(4) 掌握累加、累乘的处理方法。
(5) 掌握计数问题的编写技巧,如何控制每行输出元素个数。
2.3.2 知识要点
循环就是反复执行一段代码,直到满足结束条件。循环语句一般包括初始化、循环体、迭代和判断4部分。
1 while循环与do while循环的使用差异
while语句的格式:
while (条件表达式) {
循环体
}
特点是“先判断、后执行”,循环体有可能执行0次。
do…while循环的格式:
do
{
循环体
} while (条件表达式)
特点是“先执行,后判断”,循环体至少要执行1次。
建议: 在程序设计中尽量不用do while循环,而用while循环。
2 for循环与while循环的对应关系
for (控制变量赋初值;循环条件;增值) {
循环体
}
等价于:
控制变量赋初值;
While (循环条件) {
循环体;
控制变量增值;
}
注意几点:
(1)for循环的执行过程是先做初始化,然后判断是否满足结束条件,若满足,则执行循环体,在执行完循环体后进行迭代增值。
(2)初始化部分和增值部分可以使用逗号语句执行多个操作;
(3)三部分均为空,写成for(;;)相当于一个无限循环。
3 continue和break语句的作用
l continue---跳过之后的语句,继续下一轮循环;
l break---跳出直接所处循环。
l 带标号的continue可以回到标号指定的那级循环的下一轮执行。
l 带标号的break可以跳出标号指定的那级循环。
4 常见问题处理
(1)累加问题的解决办法—累加变量的初值设置在循环外,通常赋0为初值;
(2)如何利用循环求阶乘—累乘,在循环外设置变量初值为1;
(3)如何控制每行的输出数据个数(计数问题);
(4)如何产生一定范围的随机整数。Math.random()产生的数是0到1之间的小数,不包括0和1,要产生随机整数必须先放大再取整。
2.3.3 样例程序
样例1:输入一批学生成绩,以-1作为结束标记
(1)统计这批学生中,不及格、及格、中等、良好、优秀的人数。
(2)求这批学生的平均分。
【分析】根据要求不难看出这是一个计数和累加问题。学生数量不确定,但有一个结束标记(-1),该问题从总体结构是一个循环处理问题,可采用while循环,当输入数据为-1时结束循环。为了统计各种情况的人数,需要设立相应的计数变量,并给其赋初值0,另外为了求平均分,必须计算总分,也就是计算出所有学生成绩的累加和,然后除总人数即可得到平均。
【参考程序】
import java.io.*;
public class Score{
public static void main(String args[]) throws IOException {
int s=0,b=0,c=0,d=0,e=0,f=0; //变量赋初值
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
int a=Integer.parseInt(br.readLine()); //读取一个整数
while(a!=-1){
s+=a; //累加
switch(a/10 ) {
case 0:
case 1:
case 2:
case 3:
case 4:
case 5: b++;break; //计数增1
case 6: c++;break;
case 7: d++;break;
case 8: e++;break;
case 9: f++;break;
}
a=Integer.parseInt(br.readLine());
}
System.out.println("优秀人数:"+f);
System.out.println("良好人数:"+e);
System.out.println("中等人数: "+d);
System.out.println("及格人数:"+c);
System.out.println("不及格人数:"+b);
int average=s/(b+c+d+e+f); //求平均成绩
System.out.println("平均分="+average);
}
}
【说明】程序流图见图4-1,程序总体结构上是一个循环问题,在循环内部要分情况统计各分数段人数,包含一个是switch语句。在输入数据时未处理异常,所以在main方法的头部增加throws IOException声明该方法会抛出IO异常。
【编程技巧】
(1) 用while循环控制数据的录入和处理过程,-1作为循环的结束标记;注意循环体的最后要有输入数据的语句,以便得到新的处理数据。
(2) 如何将各分数档按情况进行分别处理,掌握除10取整后得到数据的特征。
(3) 记住累加和计数问题的处理技巧。
样例2:找10~100之间能被3或5整除的数,每行输出5个数
【参考程序】
public class A{
public static void main(String arge[]){
int k=10; //循环控制变量,从10变化到100
int m=0; //用于统计输出数的个数
while(k<=100){ //循环的终值为100
if(k%3==0||k%5==0){ //被3或5整除
m++;
System.out.print(k+"\t");
if (m%5==0) //控制每隔5个输出数换一行
System.out.println( );
}
k++; //循环控制变量增值
}
}
}
【说明】本程序是找出一定范围内(10~100)查找满足条件的数,这里有两个关键,一是如何表达一个数被3或5整除,用到求余运算符和逻辑或;二是为了控制每行输出5个数,必须对输出的数进行统计,因此,本程序的实质也要用到计数。注意,print和println的差别。
【编程技巧】
(1) 3或5整除的逻辑表达问题。
(2) 如何控制一行输出5个数。
样例3:编写一个程序从键盘输入10个整数,将最大、最小的整数找出来输出。
【参考程序】
import java.io.*;
public class Find {
public static void main(String a[]) throws IOException{
int m=0,n=Integer.MAX_VALUE; //用m,n存放需求的最大、最小整数
BufferedReader br=
new BufferedReader(new InputStreamReader(System.in));
for (int k=1;k<=10;k++) {
int x=Integer.parseInt(br.readLine());
if (x>m) m=x; //如果比最大的还大,那x成为最大的.
if (x<n) n=x;
}
System.out.println("最大整数="+m);
System.out.println("最小整数="+n);
}
}
【编程技巧】
(1) 分别引入两个变量m,n用来保存所求的最大与最小数值。在循环外为这两个变量假定一个值(为多大合适),然后在循环内将其他值与其比较。也可以先假定第一个数据为最大、最小,然后将剩余数据与其比较。
(2)不要忘记将获取新数据的输入语句放在循环内。
(3)结束循环后输出结果。
样例4:计算算式: 1+21+22+23+…+2n (注:n由键盘输入)
【参考程序1】
public class Twoadd {
public static void main(String args[]) {
int n=Integer.parseInt(args[0]);
long sum=1;
for (int k=1;k<=n;k++) {
sum = sum +(long)Math.pow(2,k); //用Math类的pow方法求2k
}
System.out.println("result="+sum);
}
}
【参考程序2】
public class Twoadd {
public static void main(String args[]) {
int n=Integer.parseInt(args[0]); //从命令行输入n
long sum=1; //保存累加和
long x=1; //被加项
for (int k=1;k<=n;k++) {
x=x*2; //求下一个被加项时,只要在前一项的基础上乘2
sum=sum+x;
}
System.out.println("result="+sum);
}
}
【说明】“参考程序1”最直观,但“参考程序2”比“参考程序1”要好,利用Math.pow(2,k)求每个累加项花费的时间长,为了完成计算,在pow方法内要执行一段计算程序。而“参考程序2”求累加项则是一个乘法运算,这里利用了前后两个累加项的变化特点。甚至简单写成x=x+x形式的加法运算更快,但可读性不如x=x*2。
【编程技巧】
(1) 用循环组织累加,在循环外给累加变量赋初值,在循环内将累加项加到累加变量上;
(2) 分析累加项的变化规律,尤其是前后项之间的关系。
(3) 用Math类的pow方法求2的k次方,由于该方法返回为一个实数,所以要用强制转换为long型才能累加到sum上。
样例5:从键盘输入一个长整数,求其各位数字之和。
【分析】这里的关键的如何得到各位数字,注意到得到一个整数的最低位数字可用除10求余数的办法,而要得到该整数的除最低位外的数只要用除10取整即可。因此,利用循环即可将一个整数的所有各位数字取出。
【参考程序】
public class fang {
public static void main (String args[]) {
int a,m=0;
a=Integer.parseInt(args[0]); //从命令行输入a
while(a>0) {
m+=a%10; //累加计算各位数字
a=a/10;
}
System.out.print(a+"的各位数字之和="+m);
}
}
【编程技巧】
(4) 如何取一个数的最低位;
(5) 如何计算去掉最低进后的数;
(6) 如何设置循环的条件。
【思考】如何修改程序,使程序的输出形式为: 54237=5+4+2+3+7=21
样例6:计算n至少多大时,以下不等式成立。
1+1/2+1/3+……+1/n>10
【参考程序】
public class Limit {
public static void main(String args[]) {
int n=0;
double s=0;
while (s<=10) {
n=n+1; // n的值增加1
s=s+1.0/n; // 进行累加
}
System.out.println("n="+n); //输出最后的n
}
}
【运行结果】
n=12367
【编程技巧】
(1) 累加一定要表示为1.0/n的形式,如果只写1/n则只要n大于1结果均为0。
(2) 循环条件的表达,以累加和的结果小于等于10为条件。结束循环时,累加和大于10,n就是所求的结果。
样例7:利用随机函数产生10道两位数的加法题,判断用户得分。
提示:产生随机数用以下办法
x=(int)(10+Math.random()*90)
程序运行界面为:
12+34=? xx
45+67=? xx
...
你的得分为:70
【分析】出10道题,总体是个循环问题,每一道题先要产生出试题,显示试题给用户,然后,获取用户的解答,比较用户解答与计算机的计算值是否相等,如果相等,就得分。循环结束输出得分。
【参考程序】
import java.io.*;
public class AddTest{
public static void main(String args[]) throws IOException {
int x,y,z,score=0;
BufferedReader br=
new BufferedReader(new InputStreamReader(System.in));
for (int i=0;i<10;i++){ //循环处理10道题
x =(int)(10+Math.random()*90); //产生1个数
y =(int)(10+Math.random()*90); //产生另一个数
System.out.print(x+"+"+y+"=? "); //提示加法式给用户
z =Integer.parseInt(br.readLine()); //用户输入解答
if( x+y == z) score+=10; //解答正确,得10分
}
System.out.println("你的得分:"+score);
}
}
【编程技巧】
(1) 利用循环控制出10道题;
(2) 利用随机函数产生一定范围内的整数的方法;
(3) 提示用户,获取输入,进行比较判断得分的逻辑顺序表达。
(4) 循环结束输出判分结果。
2.3.4 上机练习
² 基本题
1)写一个程序输入一个整数n,输出相应三角形。例如:N=4,则三角形如下:
#
##
###
####
import java.util.Scanner;
public class a{
public static void main(String[] args)
{ int i,j;
Scanner s=new Scanner(System.in);
System.out.println("please input n");
int n=s.nextInt();
for(i=1;i<=n;i++)
{
for(j=1;j<=i;j++)
System.out.print('#'+"\t");
System.out.println();
}
}
}
运行结果:
please input n
5
#
# #
# # #
# # # #
# # # # #
2) 计算算式: 1-1/2+1/3-1/4+1/5-…-1/100
public class test{
public static void main (String args[]){
float a=1,b=1,sum=0;
while(b<=100){
sum=sum+a/b;
a=-a;
b=b+1;
}
System.out.println("sum="+sum);
}
}
运行结果为:
sum=0.6881719
3) 输出九九乘法表,格式如下:
1*1=1 1*1=2 1*3=3 ……
2*1=1 2*2=2 2*3=3 ……
……
9*1=1 9*2=18 9*3=27 ……
public class T {
public static void main(String args[]){
for(int i=1;i<=9;i++){
for(int j=1;j<=9;j++){
System.out.print(i+"*"+j+"="+j*i+"\t");
}
System.out.println();
}
}
}
4) 编写一个程序,用于输出Fibonacci数列的前20项。
public class test
{
public static int fib(int n)
{
if(n==1 || n==2)return 1;
else
return fib(n-1)+fib(n-2);
}
public static void main(String[] args)
{
int[] f=new int[20];
for(int i=0;i<20;i++)
f[i]=fib(i+1);
for(int i=0;i<20;i++)
{
if(i%5==0)System.out.println();
System.out.print(f[i]+" ");
}
}
}
运行结果为:
1 1 2 3 5
8 13 21 34 55
89 144 233 377 610
987 1597 2584 4181 6765
5) 编写一个程序,输出90度以内的各度的sin()函数值。
import java.util.Scanner;
class a{
public static void main(String arg[]) {
Scanner s=new Scanner(System.in);
System.out.println("please input a:");
double a=s.nextDouble();
if (a< 0 || a > 90){
System.out.println("Error");
} else {
double x1 = Math.toRadians(a); //将角度转变化弧度 //求出正弦
double x2 = (double)(Math.round(Math.sin(x1)*100))/1000;//保留三位小数
System.out.println(x2);
}
}
}
please input a:
30
0.5
² 提高题
1) 编写一个猜数的应用程序,用随机函数产生一个10到99的随机数。根据猜中使用的次数x计算得分。每次猜完给出是大于还是小于的提示。
注:得分计算办法:110-x*10 ;(其中,x为猜的次数)
import java.io.*;
public class test {
int time;
int number;
public test(){
buildNum();
}
public void buildNum(){
number=(int) Math.round(Math.random()*89);
number+=10;
time = 0;
}
public boolean guess(int num){
time++;
if(num == number)
return true;
System.out.println(num-number>0?"more":"less");
return false;
}
public int count(){
return 110-10*time;
}
public static void main(String[] args) {
boolean flag = false;
int read=0;
String sTemp;
InputStreamReader i = new InputStreamReader(System.in);
BufferedReader bufReader = new BufferedReader(i);
test a = new test();
do{
System.out.println("请输入一个数字");
try {
sTemp=bufReader.readLine();
read = Integer.parseInt(sTemp);
} catch(NumberFormatException e){
System.out.println("输入的不是数字");
continue;
}catch (IOException e) {
e.printStackTrace();
return;
}
flag = a.guess(read);
}while(!flag);
System.out.println("你的得分为:"+a.count());
}
}
运行结果为:
请输入一个数字
69
more
请输入一个数字
57
more
请输入一个数字
40
more
请输入一个数字
23
more
请输入一个数字
12
less
请输入一个数字
18
less
请输入一个数字
20
你的得分为:40
2)找出1~100之间拥有除数最多的数。
【提示】在一定范围内找目标数,所以总体上是一个循环问题。对于每个被检测的数,要统计出其拥有除数的个数,这又是个循环问题,也就是在外循环内有内循环。为了求出拥有除数最多的哪个数,还涉及比较问题,所以要引入两个变量记下符合条件的这个数以及最多拥有的除数个数,在每次考察一个数的除数个数后要与最多者进行比较,从而决定是否要修改最多者。
public class test {
public static void main(String[] args) {
int len = 100;
for(int i = 1; i <= len; i ++){
int num = 0;
for(int j = 1; j <= i; j ++) {
if(i % j == 0) {
num ++;
System.out.println(j);
}
}
System.out.println(i + " 除数个数: " + num);
}
}
}
3) 编写一个人与计算机对拿火柴的游戏程序。利用随机函数Math.random()产生火柴数量(20~50), 每次最多拿3根,拿到最后一根为胜者。
import java.util.Scanner;
public class test {
private int Number;
private int n;
public test(){
Number=(int)(Math.random()*31)+20;
n=2;
System.out.println("一共产生"+Number+"根火柴!");
}
public void play(){
computerplay();
while(Number!=0){
int temp;
while(true){
System.out.println("输入你准备取走的火柴数1-"+n+"之间的数!");
Scanner sca=new Scanner(System.in);
temp=sca.nextInt();
if(temp>0 && temp<=n){
break;
}
}
System.out.println("你取走"+temp+"根火柴!");
for(int i=0;i<temp;i++){
Number-- ;
System.out.println("还剩下"+Number+"根火柴!");
}
if(Number<=0){
System.out.println("玩家胜");
System.exit(0);
}
if((Number%n)==0){
computerplay();
}else{
computerplay(Number%n);
}
if(Number<=0){
System.out.println("电脑胜");
System.exit(0);
}
}
}
public void computerplay(){
System.out.println("电脑取火柴!");
int Rand=(int)(Math.random()*n+1);
System.out.println("电脑取走"+Rand+"根火柴!");
for(int i=0;i<Rand;i++){
Number-- ;
System.out.println("还剩下"+Number+"根火柴!");
}
}
public void computerplay(int Rand){
System.out.println("电脑取火柴!");
System.out.println("电脑取走"+Rand+"根火柴!");
for(int i=0;i<Rand;i++){
Number-- ;
System.out.println("还剩下"+Number+"根火柴!");
}
}
public static void main(String[] args) {
test tb=new test();
tb.play();
}
}
要求:游戏过程要显示火柴总数,选择谁先拿;每步要显示剩余火柴数量,以及计算机拿的数量,并提示用户输入拿多少;结束时显示谁是胜者。
【解题算法提示】
(1) 产生火柴总数(amount);
(2) 决定随先拿(whoplay:1--人, 2--计算机);
(3) 定义一个变量保存剩余火柴数量(remain)=amount ;
(4) 当remain>0 循环
4.1 根据whoplay的值决定是计算机拿x根还是提示人拿x根;计算机拿时最好带有智能,人拿时要限制输入数量。
4.2 修改 whoplay的值;
4.3 修改remain的值;
(5) 根据whoplay的值决定胜者
4)某地刑侦大队对涉及六个嫌疑人的一桩疑案进行分析: A、B至少有一人作案; A、E、F三人中至少有两人参与作案; A、D不可能是同案犯; B、C或同时作案,或与本案无关; C、D中有且仅有一人作案;如果D没有参与作案,则E也不可能参与作案。 试编一程序,将作案人找出来。
Public class T {
public static void main(String[] args) {
String[] persons = { "A", "B", "C", "D", "E", "F" };
int A = 'A';
System.out.println("f : " + A);
for (int i = 0; i <= 'F'; i++) {
int t = i;
int num[] = new int[6];
int j = 5;
for (; j >= 0; j--) {// 换成二进制数码,保存在一个6个元素的一维数组中
if (t / 2 > 0) {
num[j] = t % 2;
t = t / 2;
} else {
num[j] = t;
break;
}
}
// num[0]--num[5]代表A--F
// 代表AB至少有一个人作案
if (num[0] + num[1] >= 1) {
// AEF 至少2个人作案
if (num[0] + num[4] + num[5] >= 2) {
// AD 不是同案犯。但可能都没作案或其中一个作案
if (num[0] + num[3] <= 1) {
// BC 同时作案,或者同时没作案
if ((num[1] + num[2] == 0 || num[1] + num[2] == 2)) {
// CD肯定有一个人作案了
if (num[2] + num[3] == 1) {
// 如果D没作案且E也没作案,或者 D作案了了
if (num[3] == 0 && num[4] == 0 || num[3] == 1)
for (int index = 0; index < num.length; index++) {
if (num[index] == 1) {
System.out.print(persons[index]);
}
}
}
}
}
}
}
}
}
}
2.3.5 思考题
1)执行以下程序后,输出结果为
public class ex2{
public static void main(String args[]) {
int f=1;
int k;
for (k=2;k<5;k++)
f*=k;;
System.out.println(k);
}
}
A. 0 B. 1 C. 5 D. 4 E. 24
2) 设有如下类
class Loop{
public static void main(String[] agrs) {
int x=0;int y=0;
outer:
for(x=0;x<100;x++){
middle:
for(y=0;y<100;y++){
System.out.println("x="+x+"; y="+y);
if(y==10){ <<<insert code>>> }
}
}
}
}
在<<<insert code>>>处插入什么代码可以结束外循环?
A.continue middle;
B.break outer;
C.break middle;
D.continue outer;
E.none of these
3)以下代码的运行结果为:
public class Calc {
public static void main (String args []) {
int total = 0;
for (int i = 0, j = 10; total > 30; ++i, --j) {
System.out.println(" i = " + i + " : j = " + j);
total += (i + j);
}
System.out.println("Total " + total);
}
}
A. 产生运行错误
B. 产生编译错误
C. 输出 "Total 0"
D. 产生如下输出:
i = 0 : j = 10
i = 1 : j = 9
i = 2 : j = 8
Total 30
4)以下程序的运行结果为:
public class test {
public static void main(String args[]) {
int i=0, j=2;
do {
i=++i;
j--;
} while(j>0);
System.out.println(i);
}
}
A. 0 B. 1 C. 2 D.3
5)以下程序的运行结果为?
class xyz {
public static void main(String args[]) {
int i,j,k;
for (i = 0; i < 3; i++) {
for(j=1; j < 4; j++) {
for(k=2; k<5; k++) {
if((i == j
展开阅读全文