4.2.2while循环语句的应用
-
【例4.11】
在银行取款时,我们需要输入密码(由6位数字组成)。密码正确才可以进行取款操作:若连续三次输入密码错误,就会冻结账号。现在请你编写一个程序,模拟验证密码的过程。
- 输入格式:
- 每次输入6为数字
- 输出格式:
- 给出提示信息:正确、错误、冻结
-
分析:
对于用户来说,做的就是反复输入6位数字密码的操作。每出入一次密码可能有三种情况:。
- (1)输入错误,但输入次数不超过3次,输出“错误”
- (2)输入错误,输入错误次数超过3次,输出“冻结”
- (3)输入未超过三次,密码正确,输出“正确”,退出循环
- 综上,我们可以设置循环的条件为:输入次数不超过三次且输入不正确。
方法一程序如下:
#include<iostream>
using namespace std;
int main() {
int mima = 111000;
int x = 0, n = 0;
while (n < 3 && x != mima) {
n++;
cin>>x;
if (x != mima)
cout<<"错误"<<endl;
}
if (x == mima) cout<<"正确"<<endl;
else if (n == 3) cout<<"冻结"<<endl;
return 0;
}
思考:
如果将程序中的第12行和第13行写成if (n == 3) cout<<"冻结"<<endl;和elif (x == mima) cout<<"正确"<<endl;,可不可以,为什么?
【例4.12】
判定给定的正整数n是否为质数,是,输出Yes,否则,输出No。
-
分析:
根据数学知识,质数是这样的约定:除了1和它本身不再具有其他约数的数,就是质数。
-
根据约定,我们可以这样想:要判断n是不是质数,我们把2~n-1的整数挨个拿出来赋给i这个变量,然后用i去除n,如果在这个范围内我们找到一个数i能够整除n,那么就说明
除了1和n本身,n还有其他的约数,因此n就不是一个质数,如果我们从2~n始终没有找到一个能整除n的数,那说明n只有1和它本身两个约数,因此n是一个质数。
程序如下:
#include<iostream>
using namespace std;
int main() {
int n, i;
cin>>n;
i = 2;
while (n%i!=0 && i<n)
i++;
if (i > n-1)
cout<<"Yes"<<endl;
else
cout<<"No"<<endl;
return 0;
}
-
思考:
- (1)上述程序能解决大多数质数的判定。从严谨的角度考虑,程序中应该加上哪些处理,才能正确判断任意正整数是否为质数?
- (2)程序中,除数的上界我们限定为n-1,这个数字能否缩小?这个数字可以怎么优化?
【例4.13】
输入一个正整数,输出其位数。
-
分析:
当输入的正整数不是一位数时,我们要用累计的方法完成位数统计:设定计数器num,取出正整数的个位数字,初始化为1,从正整数中去除掉个位数字,对去除个位数字的正整数再取出
个位数字,num再加1,……直到这个数变为0为止。我们不难发现这就是一个循环的过程。
程序如1下:
#include<iostream>
using namespace std;
int main() {
int n, num = 0;
cin>>n;
while (n != 0) {
n /= 10;
num++;
}
cout<<num<<endl;
return 0;
}
-
思考:
- 如果我们将程序修改为“输入一个正整数,并计算该正整数各个位上的数字之和是多少?”程序应该怎么改?。
【例4.14】
输入任意两个自然数,求他们的最大公约数。
-
方法一分析:
求任意两个数a和b的最大公约数,可以想到公约数最大的可能就是a和b两个数中的较小者min,最小的可能是1.所以设最大公约数gcd从min开始进行判断,若gcd>1并且没有同时被a
和b整除,就将gcd减1,重复判断是否整除。
程序如下:
#include<iostream>
using namespace std;
int main() {
int a, b, gcd;
cin>>a>>b;
gcd = a > b ? b : a;
while (gcd > 1 && (a%gcd != 0 || b%gcd != 0))
gcd--;
cout<<gcd<<endl;
return 0;
}
-
方法二分析:
这里我们来学习一个数学技巧——辗转相除法:辗转相除法也叫欧几里得算法,对任意两个自然数a和b,如果q和r是a除以b的商和余数,那么a和b的最大公约数等于b和r的最大公约数。
- 具体的求解过程描述如下;
- (1)a÷b=q……r1
- (2)若r1=0,则a和b的最大公约数就是b。
- (3)若r1!=0,则继续做除法取余运算b÷r1=q……r2。
- (4)若r2=0,则r1和r2的最大公约数就是r2。
- (5)若r1!=0,则继续做除法取余运算r1÷r2=q……r3。
- (6)如此重复下去,直到出现整除为止,余数为0时的除数就是a和b的最大公约数。
程序如下:
#include<iostream>
using namespace std;
int main() {
int a, b, r;
cin>>a>>b;
r = a % b;
while (r != 0) {
a = b;
b = r;
r = a % b;
}
cout<<b<<endl;
return 0;
}
-
说明:
- 在使用循环解决实际问题是,具体使用哪一种语句并没有硬性规定,往往跟我们个人习惯和要解决的问题有关。