本篇着重介绍一种算法实现的思想,不针对具体的语言及环境,通过几个经典的例题,说明设计算法的过程中,如何将一个复杂的问题简单化,最终求得我们想要的结果。
所谓“分而治之” 就是把一个复杂的算法问题按一定的“分解”方法分为等价的规模较小的若干部分,然后逐个解决,分别找出各部分的解,把各部分的解组成整个问题的解,这种朴素的思想来源于人们生活与工作的经验,也完全适合于技术领域。
下面的几道经典例题选自与谭浩强老师编著的《C程序设计》(第五版)
例题1:求解(即求1!+2!+......+20!)
解题思路:本题可以分解成为两部分:一是求各自的阶乘,二是将这些阶乘所得数值进行加法运算,对于前者,我们可以设置一个for循环进行累乘操作,而对于后者,需设置一个temp=0进行累加操作,算法如下:(用C语言实现)(这里为方便理解和检查,改成求到加3的阶乘)
void function4() {
int i;
int sum = 0;
for (i = 1; i <= 3; i++) {//外层大for循环表示一共要进行几次加和
int j;
int temp = 1;
for (j = 0; j < i; j++) {
temp = temp * (j + 1);//计算阶乘
}
sum = sum + temp;//内部for循环每执行完一次,说明算出了一个数的阶乘,那么进行相加
}
printf("%d",sum);//打印输出最终结果
}
对于新手而言,需要提醒的是,无论是累成还是累加,都要预先设置一个变量,累成初始化为1,累加初始化为0,因为我大学刚开始用C写算法的时候,犯过的一个错误,是直接用设置的变量进行累加或累乘,例如这个题不要写成temp=temp*(temp+1)之类的
例题2:求Sn=a+aa+aaa+...+aa..a(n个a),其中a是一个数字,n表示a的位数,n由键盘输入。
解题思路:本题可分为两部分,一部分是求aa..a,而另一部分是对这些值进行累加,关键在于如何通过键盘输入的a值,求得aa..a。例如从键盘输入a=2,那么22=2*10+2,222=2*10*10+22,那么,我们只需设置int temp=0 ; 之后进行for循环:temp=temp+a ; a=a*10 ; 代码段如下:
void function3() {
int a = 0;
printf("请输入1到9的整数:");
scanf("%d", &a);
printf("请输入累加次数:");
int count = 0;
scanf("%d", &count);
int sum = 0;
int temp1 = 0;
while (count > 0) {
temp1 = temp1 + a;
sum = sum + temp1;
a = a * 10;
count--;
}
printf("最终结果是:%d\n", sum);
}
例题3:求解:
本题仍分两步,较为简单,直接上程序:
void function5() {
int i, j = 0;
for (i = 1; i <= 100; i++){
j = j + i;
}
int m, n = 1;
for (m = 1; m <= 50; m++) {
n = n + m * m;
}
int k, h = 0;
for (k = 1; k <= 10; k++) {
h = h + 1 / k;
}
int total = 0;
total = j + n + h;
printf("最终结果是:%d\n", total);
}
例题4:完数的求解,编程找出1000以内的所有完数,并输出其因子(注:完数,一个数如果恰好等于它的因子之和,那么这个数就称为完数)
思路:本题如果想要一气呵成,有些不着头绪,因此,本题分为两部分:首先我们不妨先判断,对于待求数而言,什么时候,它是一个完数;第二,如果待求数是完数,那么我们如何输出其全部的因子?
void function6() {
int i;
for (i = 1; i <= 1000; i++) {
int j;
int temp = 0;
for (j = 1; j < i; j++) {//第一部分:什么时候是完数
if (i % j == 0) {
temp = temp + j;
}
}
if (temp == i) {//第二部分:是完数时,单独输出其因子
printf("%d是完数,其组成的因子是:", i);
for (int j = 1; j < i; j++) {
if (i % j == 0) {
printf("%3d", j);
}
}
printf("\n");
}
}
}
编程中,有时需要经常将一个数进行暂存,因为这个数在后续运算过程中会改变,例如本题:
计算1+1/3+1/5+...+
void 输出分数累加1() {
float a = 1;
int count = 0;
printf("输入迭代次数:");
scanf("%d", &count);
float temp_a = a;//设置暂存变量
while (count > 0) {
a = a + 1 / (temp_a + 2);
temp_a = temp_a + 2;
count--;
}
printf("计算结果是:%f", a);
}