加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
xunhuan.cpp 15.39 KB
一键复制 编辑 原始数据 按行查看 历史
一壶李 提交于 2020-11-04 20:31 . add xunhuan.cpp.
////////////////////////////第四章////////////////////////////////
#include <stdio.h>
#include <math.h> /* 程序中调用绝对值函数 fabs(),需包含 math.h */
#include<stdlib.h>
#include<time.h>
/* 【例4-1】使用格里高利公式求π的近似值,精度要求:最后一项的绝对值小于0.0001 */
int ex_4_1_pi(void)
{
int denominator, flag;
double item, pi; /* pi 用于存放累加和 */
/* 循环初始化 */
flag = 1; /* flag 表示第 i 项的符号,初始为正 */
denominator = 1; /* denominator表示第 i 项的分母,初始为1 */
item = 1.0; /* item 中存放第 i 项的值,初值取 1 */
pi = 0; /* 置累加和 pi 的初值为0 */
while (fabs(item) >= 0.0001) { /* 当|item| ≥ 0.0001时,执行循环 */
item = flag * 1.0 / denominator; /* 计算第 i 项的值 */
pi = pi + item; /* 累加第 i 项的值 */
flag = -flag; /* 改变符号,为下一次循环做准备 */
denominator = denominator + 2; /* 分母递增2 ,为下一次循环做准备 */
}
pi = pi * 4; /* 循环计算的结果是 pi/4 */
printf("pi = %.4f\n", pi);
return 0;
}
/* 【例4-2】更改例3-3。从键盘输入一批学生的成绩,计算平均成绩,并统计不及格学生的人数。 */
int ex_4_2_average_point(void)
{
int count, num; /* num 记录输入的个数,count记录不及格学生人数 */
double grade, total; /* 分别存放成绩、成绩之和 */
num = 0;
total = 0;
count = 0;
printf("Enter grades: "); /* 输入提示 */
scanf("%lf", &grade); /* 输入第一个数据,%lf中的l是字母 */
/* 当输入数据 grad 大于等于0时,执行循环 */
while (grade >= 0) {
total = total + grade; /* 累加成绩 */
num++; /* 计数 */
if (grade < 60)
count++;
scanf("%lf", &grade); /* 读入一个新数据,为下次循环做准备 */
}
if (num != 0) {
printf("Grade average is %.2f\n", total / num);
printf("Number of failures is %d\n", count);
}
else
printf("Grade average is 0\n");
return 0;
}
/* 【例4-3】从键盘读入一个整数,统计该数的位数。例如,输入12534,输出5;输入-99,输出2;输入0,输出1。*/
int ex_4_3_number_bits(void)
{
int count, number; /* count 记录整数number的位数 */
count = 0;
printf("Enter a number:"); /* 输入提示 */
scanf("%d", &number);
if (number < 0) number = -number; /* 将输入的负数转换为正数 */
do {
number = number / 10; /* 整除后减少一位个位数,组成一个新数 */
count++; /* 位数加1 */
} while (number != 0); /* 判断循环条件 */
printf("It contains %d digits.\n", count);
return 0;
}
/* 【例4-4-1】输入一个正整数m,判断它是否为素数。素数就是只能被1和自身整除的正整数,1不是素数,2是素数。*/
int ex_4_4_1_prime(void)
{
int i, m;
printf("Enter a number: "); /* 输入提示 */
scanf("%d", &m);
for (i = 2; i <= m / 2; i++) /* 第9行 */
if (m % i == 0)
break; /* 若m能被某个i整除,则m不是素数,提前结束循环 */
if (i > m / 2 && m != 1) /* 若循环正常结束,说明m不能被任何一个i整除,则m是素数 */
printf("%d is a prime number! \n", m);
else
printf("No!\n"); /* 第15行 */
return 0;
}
/* 【例4-4-2】输入一个正整数m,判断它是否为素数。素数就是只能被1和自身整除的正整数,1不是素数,2是素数。*/
int ex_4_4_2_prime_2(void)
{
int i, flag, m;
flag = 1;
printf("Enter a number: "); /* 输入提示 */
scanf("%d", &m);
if (m == 1) flag = 0;
for (i = 2; i <= m / 2; i++)
if (m % i == 0) {
flag = 0;
break; /* 若m能被某个i整除,则m不是素数,提前结束循环 */
}
if (flag == 1)
printf("%d is a prime number! \n", m);
else
printf("No!\n");
return 0;
}
/* 【例4-5-1】改进例3-1简单的猜数游戏。输入你所猜的正整数(假定1~100内),与计算机产生的被猜数比较,若相等,显示猜中;若不等,显示与被猜数的大小关系,最多允许猜7次。 */
int ex_4_5_1_guess_number_for(void)
{
int count = 0, flag, mynumber, yournumber;
mynumber = 38; /* 计算机产生的被猜数 */
flag = 0; /* flag的值为0表示没猜中,为1表示猜中了*/
for (count = 1; count <= 7; count++) { /* 最多能猜7次*/
printf("Enter your number: "); /* 提示输入你所猜的整数 */
scanf("%d", &yournumber);
if (yournumber == mynumber) { /* 若相等,显示猜中 */
printf("Lucky You!\n");
flag = 1;
break; /* 已猜中,终止循环 */
}
else
if (yournumber>mynumber)
printf("Too big\n");
else
printf("Too small\n");
}
if (flag == 0) /* 超过7次还没猜中,提示游戏结束*/
printf("Game Over!\n");
return 0;
}
/* 【例4-5-2】改进例3-1简单的猜数游戏。输入你所猜的正整数(假定1~100内),与计算机随机产生的被猜数比较,若相等,显示猜中;若不等,显示与被猜数的大小关系,最多允许猜7次。 */
int ex_4_5_2_guess_number_while(void)
{
int count = 0, flag, mynumber, yournumber;
srand(time(0));
mynumber = rand() % 100 + 1; /* 计算机随机产生一个1~100之间的被猜数 */
flag = 0; /* flag的值为0表示没猜中,为1表示猜中了*/
while (count < 7) { /* 最多能猜7次*/
printf("Enter your number: "); /* 提示输入你所猜的整数 */
scanf("%d", &yournumber);
count++;
if (yournumber == mynumber) { /* 若相等,显示猜中 */
printf("Lucky You!\n");
flag = 1;
break; /* 已猜中,终止循环 */
}
else
if (yournumber>mynumber)
printf("Too big\n");
else
printf("Too small\n");
}
if (flag == 0) /* 超过7次还没猜中,提示游戏结束*/
printf("Game Over!\n");
return 0;
}
/* 【例4-6】计算1! + 2! + 3! + … + 100!。要求定义和调用函数fact(n)计算n的阶乘。 */
double fact(int n)
{
int i;
double result; /* 变量 result 中存放阶乘的值 */
result = 1; /* 置阶乘 result 的初值为1 */
for (i = 1; i <= n; i++) /* 循环执行n次,计算n! */
result = result * i;
return result; /* 把结果回送主函数 */
}
int ex_4_6_factorial_sum_func(void)
{
int i;
double sum;
sum = 0;
for (i = 1; i <= 100; i++)
sum = sum + fact(i); /* 调用fact(i)求i!,共重复100次 */
printf("1! + 2! + ... + 100! = %e\n", sum); /* 用指数形式输出结果 */
return 0;
}
/* 【例4-7】计算1! + 2! + 3! + … + 100!。要求使用嵌套循环 */
int ex_4_7_factorial_sum_2loop(void)
{
int i, j;
double item, sum; /* 变量 item 中存放阶乘的值 */
sum = 0;
for (i = 1; i <= 100; i++) { /* 外层循环执行100次,求累加和 */
item = 1; /* 置 item 的初值为1,以保证每次求阶乘都从1开始连乘 */
for (j = 1; j <= i; j++) /* 内层循环重复i次,算出item = i! */
item = item * j;
sum = sum + item; /* 把 i! 累加到sum中 */
}
printf("1! + 2! + ... + 100! = %e\n", sum); /* 用指数形式输出结果 */
return 0;
}
/* 【例4-8】求最值问题。输入一批学生的成绩,找出最高分 */
int ex_4_8_highest_score(void)
{
int i, mark, max, n; /* max中放最高分 */
printf("Enter n: "); /* 输入提示 */
scanf("%d", &n); /* 输入数据个数 */
printf("Enter %d marks: ", n); /* 提示输入n个成绩 */
scanf("%d", &mark); /* 读入第一个成绩 */
max = mark; /* 假设第一个成绩是最高分 */
for (i = 1; i < n; i++) { /* 由于已经读了一个数,循环执行n-1次 */
scanf("%d", &mark); /* 读入下一个成绩 */
if (max < mark) /* 如果该成绩比最高分高 */
max = mark; /* 再假设该成绩为最高分 */
}
printf("Max = %d\n", max);
return 0;
}
/* 【例4-9】逆序问题。输入一个正整数,将其逆序输出。例如,输入12345,输出54321。*/
int ex_4_9_reverse(void)
{
int x;
printf("Enter x: "); /* 输入提示 */
scanf("%d", &x);
while (x != 0) {
printf("%d ", x % 10);
x = x / 10;
}
return 0;
}
/* 【例4-10】素数问题。求100以内的全部素数,每行输出10个。素数就是只能被1和自身整除的正整数,1不是素数,2是素数。 */
int ex_4_10_prime_in_100(void)
{
int count, i;
double m, n;
count = 0; /* count记录素数的个数,用于控制输出格式 */
for (m = 2; m <= 100; m++) {
n = sqrt(m);
for (i = 2; i <= n; i++)
if ((int)m % i == 0)
break;
if (i > n) { /* 如果m是素数 */
printf("%6d", m); /* 输出m */
count++; /* 累加已经输出的素数个数 */
if (count % 10 == 0) /* 如果count是10的倍数,换行 */
printf("\n");
}
}
printf("\n");
return 0;
}
/* 【例4-11】菲波那契数列问题。输出菲波那契(Fibonacci)序列的前10项:1,1,2,3,5,8,13,21,34,55。 */
int ex_4_11_Fibonacci(void)
{
int i, x1, x2, x; /* x1和x2依次代表前两项,x表示其后一项 */
x1 = 1; /* 头两项都是1 */
x2 = 1;
printf("%6d%6d", x1, x2); /* 先输出头两项 */
for (i = 1; i <= 8; i++) { /* 循环输出后8项 */
x = x1 + x2; /* 计算新项 */
printf("%6d", x);
x1 = x2; /* 更新x1和x2,为下一次计算新项x作准备*/
x2 = x;
}
printf("\n");
return 0;
}
/* 【例4-12-1】穷举算法。(中国古典算术问题)某工地需要搬运砖块,已知男人一人搬3块,女人一人搬2块,小孩两人搬1块。有多少种搬法用45人正好搬45块砖? */
int ex_4_12_1_move_brick_3for(void)
{
int child, men, women;
for (men = 0; men <= 45; men++)
for (women = 0; women <= 45; women++)
for (child = 0; child <= 45; child++)
if (men + women + child == 45 && men * 3 + women * 2 + child*0.5 == 45)
printf("men=%d,women=%d,child=%d\n", men, women, child);
return 0;
}
/* 【例4-12-2】穷举算法。(中国古典算术问题)某工地需要搬运砖块,已知男人一人搬3块,女人一人搬2块,小孩两人搬1块。有多少种搬法用45人正好搬45块砖? */
int ex_4_12_2_move_brick_2for(void)
{
int child, women, men;
for (men = 0; men <= 15; men++)
for (women = 0; women <= 22; women++) {
child = 45 - women - men;
if (men * 3 + women * 2 + child * 0.5 == 45)
printf("men=%d,women=%d,child=%d\n", men, women, child);
}
return 0;
}
//循环核心 = 每走一步找相同 + 特殊情况(即打断循环的2种)
/* 【例-循环的特殊打断,2种】 一个正整数m,判断它是否为素数。素数就是只能被1和自身整除的正整数,1不是素数,2是素数。*/
int loop_special2(void)
{
int i, isPrime=1, m; //isPrime=1 代表是素数,是个标记。
printf("Enter a number: "); /* 输入提示 */
scanf("%d", &m);
for (i = 1; i <= m-1; i++) {
if(i == 1) { //i等于1时,当前步跳过,继续后面的循环步骤。 特殊1:跳过当前步,继续后面循环
continue;
}
if (m % i == 0) {
isPrime = 0;
break; //若m能被某个i整除,则m不是素数,提前结束循环。 特殊2: 结束后面循环
}
}
if(m==1){
isPrime = 0;
}
if (isPrime == 1)
printf("%d is a prime number! \n", m);
else
printf("%d is not a prime number! \n", m);
return 0;
}
/*屏幕上显示1 2 3 4
第1步:打印1
第2步:打印2
第3步:打印3
第4步:打印4
每步做的都很像,都是打印当前步数。故:
四步
{ 打印当前步数 }
三种方法: 手动/for循环/while循环/do whle循环。李老师建议用for。
*/
int loop_3type()
{
printf("%d", 1);
printf("%d", 2);
printf("%d", 3);
printf("%d", 4);
int i;
for(i=1; i<=4; i++) {
printf("%d", i);
}
i = 1;
while(i<=4) { //while后面括号里是条件成立时,就一直循环。
printf("%d", i);
i++;
}
i = 1;
do{ //while后面括号里是条件成立时,就一直循环。
printf("%d", i);
i++;
}while(i<=4);
return 0;
}
int print10()
{
return 0;
}
int main(void)
{
//loop_special2();
//loop_3type();
int choice, i;
for (i = 1; i <= 20; i++) { /* for 的循环体语句开始 */
printf("Enter choice: "); /* 输入提示 */
scanf("%d", &choice); /* 接受用户输入的编号 */
/* 根据输入的编号,将相应的价格赋给price */
switch (choice) {
case 1: loop_special2(); break;
case 2: loop_3type(); break;
//case 41: ex_4_1_pi(); break; /* 用break跳出switch语句,下同 */
//case 42: ex_4_2_average_point(); break; /* 用break跳出switch语句,下同 */
//case 43: ex_4_3_number_bits(); break;
case 441: ex_4_4_1_prime(); break;
case 442: ex_4_4_2_prime_2(); break;
//case 451: ex_4_5_1_guess_number_for(); break;
//case 452: ex_4_5_2_guess_number_while(); break;
case 46: ex_4_6_factorial_sum_func(); break;
case 47: ex_4_7_factorial_sum_2loop(); break; /* 用break跳出switch语句,下同 */
//case 48: ex_4_8_highest_score(); break; /* 用break跳出switch语句,下同 */
//case 49: ex_4_9_reverse(); break;
case 410: ex_4_10_prime_in_100(); break;
//case 411: ex_4_11_Fibonacci(); break;
//case 4121: ex_4_12_1_move_brick_3for(); break;
//case 4122: ex_4_12_2_move_brick_2for(); break;
case 413: print10(); break;
default: printf("err"); break;
}
/* 输出商品的价格 */
printf("choice = %d end\n", choice);
} /* for 的循环体语句结束 */
printf("Thanks \n"); /* 结束查询,谢谢用户使用 */
return 0;
}
//温习上面case 1和case 2
//循环练习1: 写一个函数,用for打印出12345678910,在上面switch里面增加一个case来调用它。
//结果正确后,提交至码云gitee。
//!!!注意: 老师已添加了,case 413: print10(), 你只用在它里面添加功能代码后,f10查看结果正确即可)
//注意:后面练习步骤同上,结果正确后提交至码云。
//循环练习2: 同上步骤,写一个函数,打印出 1+2+3+4+5+...+10 的结果,在上面switch里面增加一个case来调用它。
//循环练习3: 写一个函数,用scanf输入一个数,打印出其阶乘,在上面switch里面增加一个case来调用它。
//循环练习4: 同上, 打印出1! + 2! + 3! + … + 100! 提示:调用上面函数来求每个数的阶乘
//循环练习5: 同上,模仿上面case 441: ex_4_4_1_prime(), 写新函数实现同样功能。
//循环练习6: 同上,模仿上面case 410: ex_4_10_prime_in_100, 写新函数打印出100以内的素数之和。
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化