1、循环设计要点
1、设计中要注意算法的效率
2、“自顶向下”的设计方法
3、由具体到抽象设计循环结构
例题1(阶乘相加)
累加、累惩算法的设计过程
求1/1! - 1/3! + 1/5! - 1/7! + ...... + (-1)^n+1 / (2n-1)!
数学模型:Sn = Sn-1 + (-1)^n+1 /(2n-1)!
//阶乘需要每次从1开始重新计算
void operation(int n) {
int i, j, sign = 1;
double t, sum = 1; //计算总和
for (i = 2; i <= n; i++) { //2 ---n个数相加
t = 1;
for (j = 1; j <= 2 * i - 1; j++) {
t *= j; //t存阶乘
}
sign = -sign;
sum += sign / t;
}
printf("sum = %lf", sum);
return;
}
优化
void operation(int n) {
int i, j, sign = 1;
double t = 1, sum = 1; //计算总和
for (i = 2; i <= n; i++) { //2 ---n个数相加
sign = -sign;
t = t * (2 * i - 2) * (2 * i - 1); //t存起来了,然后计算每项的时候直接多乘两位就0k
sum += sign / t;
}
printf("sum = %lf", sum);
return;
}
例题2(完数)
自顶向下,就是分块写函数,由大的部分分成小的函数(部分)来解决问题
一个数如果恰好等于它的因子之和(包括1,但不包括这个数本身),这个数就称为“完数”
编写算法,找出1000之内的完数,输出格式“28 it's factors are 1,2,4,7,14”
void finished() {
int i, j, k;
int a[200];//存因子
int s;//因子的和
a[0] = 1;
for (i = 1; i <= 1000; i++) { //1000个数,一个一个来
s = 1;
k = 1;
for (j = 2; j <= i; j++) { //s已经是1,从2开始
if (i != j && i % j == 0) { //j是i的一个因子
s += j;
a[k++] = j;
}
}
if (s == i) {
printf("%d it's factors are ", i);
for (j = 0; j < k; j++) {
printf("%d,", a[j]);
}
printf("\n");
}
}
}
例题4(鞍点)
求一个矩阵的鞍点,即在行上最小,而在列上最大的点
对nxn矩阵操作,行列下标起始为0
void saddlePoint(int a[10][10]) {
int n = 10;
int i, j;
int minj = 1000;
for (i = 0; i < n; i++) {//一行一行来
for (j = 0; j < n; j++) {
if (a[i][j] < minj) {
minj = j;
}
}
for (j = 0; j < n; j++) {
if (a[i][minj] > a[j][minj]) {
continue;
}
}
if (j == n) {
printf("Saddle point is %d", a[i][minj]);
}
}
}
例题4(打印图)
1
5 2
8 6 3
10 9 7 4
//按(图中)规律输入,按(数组)顺序输出
void print(int a[10][10]) {
int n = 10;
int i, j, k = 1;
for (i = 0; i < n; i++) { //抽象出来的层数
for (j = 0; i < n - i + 1; j++) {
a[j + i][j] = k++;
}
}
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
printf("%d", a[i][j]);
}
}
}
递归设计要点
例题1(汉诺塔)
//从A--->C
void Hanio(int n, char A, char B, char C)
{
if (1 == n)
printf("%c->%c\n", A, C);
else
{
Hanio(n - 1, A, C, B);
printf("%c->%c", A, C);
Hanio(n - 1, B, A, C);
}
}
循环与递归的比较
例题1(整数拆分)
由低位到高位输出
//循环
#include<stdio.h>
void print(int n) {
while (n >= 10) {
printf("%d", n % 10);
n = n / 10;
}
printf("%d", n);
}
void main() {
print(345);
}
//递归
#include<stdio.h>
void print(int n) {
printf("%d", n % 10);
if (n < 10) {
return;
}
print(n / 10);
}
void main() {
print(345);
}
例题2(整数拆分)
由高位到低位输出
还是和例1一样,用数组存起来最后输出就ok
例题3(多个数的组合)
找出n个自然数(1---n)中取r个数的组合
//循环
void combination() {
int i, j, k, t = 0;
int n = 5, r = 3;
for (i = 1; i < n - r + 1; i++) {
for (j = i; j < n - r + 2; j++) {
for (k = j; k < n - r - 3; k++) {
t = t + 1;
printf("%d,%d,%d", i, j, k);
}
}
}
printf("total = %d", t);
}
#include<stdio.h>
int a[100] = {0};
void combination(int n, int r) {
int i, j;
for (i = n; i >= r; i--) { //执行到r,然后就剩下r-1个数了,因为在执行下去就组成不了r个数了
a[r] = i;
if (r > 1) {
combination(n-1, r-1);
}else { //输出
for (j = a[0]; j > 0; j--) {
printf("%d ", a[j]);
}
printf("\n");
}
}
}
void main() {
a[0] = 3;
combination(5, 3);
}