【例 2.1】求 1×2×3×4×5。
最原始方法:
步骤 1:先求 1×2,得到结果 2。
步骤 2:将步骤 1 得到的乘积 2 乘以 3,得到结果 6。
步骤 3:将 6 再乘以 4,得 24。
步骤 4:将 24 再乘以 5,得 120。
这样的算法虽然正确,但太繁。
改进的算法:
S1: 使 t=1
S2: 使 i=2
S3: 使 t×i, 乘积仍然放在在变量 t 中,可表示为 t×i→t
S4: 使 i 的值+1,即 i+1→i
S5: 如果 i≤5, 返回重新执行步骤 S3 以及其后的 S4 和 S5;否则,算法结束。
如果计算 100!只需将 S5:若 i≤5 改成 i≤100 即可。
如果该求 1×3×5×7×9×11,算法也只需做很少的改动:
S1: 1→t
S2: 3→i
S3: t×i→t
S4: i+2→t
S5:若 i≤11, 返回 S3,否则,结束。
该算法不仅正确,而且是计算机较好的算法,因为计算机是高速运算的自动机器,实现循环
轻而易举。
思考:若将 S5 写成:S5:若 i<11, 返回 S3;否则,结束。
#include <math.h>
#include <stdio.h>
int main()
{
int t = 1;
int i = 3;
// 求 1×2×3×4×5 的
// while (i <= 5) {
// t *= i;
// i += 1;
// }
// 求 100! (1×2×...×100) 的变种
// while (i <= 100)
// {
// t *= i;
// i += 1;
// }
// 计算1×3×5×7×9×11的乘积:
while (i <= 11)
{
t *= i;
i += 2;
}
printf("乘积结果是: %d\n", t);
return 0;
}
【例 2.2】有 50 个学生,要求将他们之中成绩在 80 分以上者打印出来。
如果,n表示学生学号,ni表示第个学生学号;g表示学生成绩,gi表示第个学生成绩;
则算法可表示如下:
S1: 1→i
S2: 如果gi≥80,则打印ni和gi,否则不打印
S3: i+1→i
S4:若 i≤50, 返回 S2,否则,结束。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
// #include "../../tools/tools/String/array_to_string.h"
#define NUM_STUDENTS 50
int main() {
int student_ids[NUM_STUDENTS];
int scores[NUM_STUDENTS];
int i;
int arr[] = {1, 2, 3, 4, 5};
// 初始化随机数种子
srand(time(NULL));
// 填充学生学号,这里简单从1到50
for (i = 0; i < NUM_STUDENTS; i++) {
student_ids[i] = i + 1;
}
// int size = sizeof(student_ids) / sizeof(student_ids[0]);
// char* str = array_to_string(student_ids, size);
// 生成随机成绩(例如,介于0到100之间)
for (i = 0; i < NUM_STUDENTS; i++) {
scores[i] = rand() % 101; // %101 保证范围在0-100
}
// 打印80分以上的学生信息
printf("成绩80分以上的学生信息:\n");
for (i = 0; i < NUM_STUDENTS; i++) {
if (scores[i] >= 80) {
printf("学生学号: %d, 成绩: %d\n", student_ids[i], scores[i]);
}
}
return 0;
}
【例 2.3】判定 2000 — 2500 年中的每一年是否闰年,将结果输出。
润年的条件:
1. 能被 4 整除,但不能被 100 整除的年份;
2. 能被 100 整除,又能被 400 整除的年份;
设 y 为被检测的年份,则算法可表示如下:
S1: 2000→y
S2:若 y 不能被 4 整除,则输出 y“不是闰年”,然后转到 S6
S3:若 y 能被 4 整除,不能被 100 整除,则输出 y“是闰年”,然后转到 S6
S4:若 y 能被 100 整除,又能被 400 整除,输出 y“是闰年” 否则输出 y“不是闰年”,
然后转到 S6
S5:输出 y“不是闰年”。
S6:y+1→y
S7:当 y≤2500 时, 返回 S2 继续执行,否则,结束。
int main() {
int y = 2000; // S1: 初始化年份为2000
while (y <= 2500) { // S7: 当y小于等于2500时循环执行
// S2: 判断能否被4整除
if (y % 4 != 0) {
printf("%d不是闰年\n", y); // 输出不是闰年
} else {
// S3: 能被4整除,继续判断能否被100整除
if (y % 100 != 0) {
printf("%d是闰年\n", y); // 输出是闰年
} else {
// S4: 能被100整除,再判断能否被400整除
if (y % 400 == 0) {
printf("%d是闰年\n", y); // 输出是闰年
} else {
printf("%d不是闰年\n", y); // 否则,不是闰年
}
}
}
y++; // S6: 年份加1,准备检查下一年
}
return 0;
}
【例 2.4】求 100
1 - 1/2 - 1/3 + … + 1/100
算法可表示如下:
S1: sigh=1
S2: sum=1
S3: deno=2
S4: sigh=(-1)×sigh
S5: term= sigh×(1/deno )
S6: term=sum+term
S7: deno= deno +1
S8:若 deno≤100,返回 S4;否则,结束。
double sum = 1.0; // S1: 初始化总和为1.0,首项为1
int sign = -1; // S2: 初始化符号变量,首项后开始为负
int deno = 2; // S3: 初始化分母为2,从第二项1/2开始
printf("计算过程:\n");
// S4-S8: 循环计算直到分母达到101(包括1/100这一项)
while (deno <= 100) {
double term = (double)sign / deno; // S5: 计算当前项,并考虑符号
// 更清晰地展示计算过程,但需注意浮点数精度限制
printf("Step %2d: Term = %+.10lf (as fraction ~ %+.10lf/%d)\n", deno-1, term, sign, deno);
sum += term; // S6: 累加到总和
sign *= -1; // S7: 反转符号,准备计算下一项
deno++; // S8: 分母递增
}
// 输出结果
printf("\n计算结果为: %.10lf\n", sum);
return 0;
【例 2.5】对一个大于或等于 3 的正整数,判断它是不是一个素数。
算法可表示如下:
S1: 输入 n 的值
S2: i=2
S3: n 被 i 除,得余数 r
S4:如果 r=0,表示 n 能被 i 整除,则打印 n“不是素数”,算法结束;否则执行 S5
S5: i+1→i
S6:如果 i≤n-1,返回 S3;否则打印 n“是素数”;然后算法结束。
改进:
S6:如果i≤ n ,返回S3;否则打印n“是素数”;然后算法结束。
int main() {
int n, i = 2;
printf("请输入一个大于或等于3的正整数: ");
scanf("%d", &n);
// 算法实现
if (n < 3) {
printf("%d 不符合输入要求(应大于或等于3的正整数)。\n", n);
} else if (n == 3) {
printf("%d 是素数。\n", n);
} else if (n % 2 == 0) {
printf("%d 不是素数。\n", n);
} else {
// 从3开始检查到n本身,步长为2,因为偶数已排除
for (; i <= n; i += 2) {
if (n % i == 0) {
printf("%d 不是素数。\n", n);
return 0; // 一旦发现有因子,直接结束
}
}
}
printf("%d 是素数。\n", n);
return 0;
}
流程图表示算法,直观形象,易于理解。
【例 2.6】将例 2.1 求 5!的算用流程图表示。
【例 2.7】将例 2.2 的算用流程图表示。
【例 2.8】将例 2.3 判定闰年的算用流程图表示。
将例 2.4 求 1-1/2+1/3-1/4+1/99-1/100
的算用流程图表示。
一个流程图包括:
1. 表示相应操作的框;
2. 带箭头的流程线;
3. 框内外必要的文字说明。
我们的任务是用计算机解题,就是用计算机实现算法;
用计算机语言表示算法必须严格遵循所用语言的语法规则。
【例 2.20】求 1×2×3×4×5 用 C 语言表示。
main()
{
int i, t;
t = 1;
i = 2;
while (i <= 5)
{
t = t * i;
i = i + 1;
}
printf(“% d”, t);
}
【例 2.21】求级数的值。
main()
{
int sigh = 1;
float deno = 2.0, sum = 1.0, term;
while (deno <= 100)
{
sigh = -sigh;
term = sigh / deno;
sum = sum + term;
deno = deno + 1;
}
printf("% f", sum);
}