1、编程的灵魂:数据结构+算法
程序 = 编程的灵魂 + 程序设计语言
数据结构是算法实现的基础,算法依赖于某种数据结构来实现。在实现一种算法的时候,往往就会相应的去构建一种适用于该算法的数据结构。
2、常用算法思路
2.1 递推算法
“步步为营”,利用已有信息推导出新的东西或结果。
顺推法:从已知条件出发,逐步推算出要解决的问题。例:斐波拉契数列可通过顺推法不断递推出新的数据。
顺推实列:斐波拉契数列,又称兔子数列
#include<stdio.h>
#define Max_month 12
int main(void)
{
int i;
int Fibonacci_sequence [Max_month]= {1,1};//the number of rabbits in the first month and the second month is 1.
for(i=2;i < Max_month;i++)
{
Fibonacci_sequence[i] = Fibonacci_sequence[i-1] + Fibonacci_sequence[i-2];
}
for(i=0;i<Max_month;i++)
{
printf("The number of the rabbit at the %d month is %d\n",i+1,Fibonacci_sequence[i]);
}
getch();
return 0;
}
逆推法:从已知结果出发,用迭代表达式逐步推算出问题的开始条件。
逆推实例如下:
已知Taelon在第36个月末(研究生3年)时连本带息要取1000元,银行月利率为:1.5%➗12。则在其入学时要准备多少钱存入银行(保证每个月末都可以取到1000元)。根据已知条件和问题,则应先求出第35个月时银行存款数:
第35个月月末存款数=(第36个月月末存款数+1000)/(1+0.015/12);第36个月月末钱已全部取出,为0
第34个月月末存款数=(第35个月月末存款数+1000)/(1+0.015/12);
.... ....
第1个月月末存款数=(第2个月月末存款数+1000)/(1+0.015/12);
#include<stdio.h>
#define Monthly_cost 1000
#define Annual_interset 0.015
int main(void)
{
double deposits[37];
int i;
deposits[36] = 0;//the deposits at the end of lasr month is zero
for(i=35;i>0;i--)
{
deposits[i] = (deposits[i+1] + Monthly_cost)/(1+Annual_interset/12);
}
for(i=36;i>0;i--)
{
printf("the deposits at the end of %d month is %.2f\n",i,deposits[i]);
}
getch();
return 0;
}
2.2枚举(穷举)算法
本质是从所有的候选答案中去搜索正确的解,使用该算法需要满足两个条件:
a.可预先确定候选答案的数量;
b.候选答案的范围在求解之前必须有一个确定的集合
枚举实例1:
算法描述题
X 算
-----------------
题题题题题题
#include<stdio.h>
int main(void)
{
int i1,i2,i3,i4,i5;
long multiplier,result;
for(i1=1;i1<=9;i1++)
{
for(i2=0;i2<=9;i2++)
{
for(i3=0;i3<=9;i3++)
{
for(i4=0;i4<=9;i4++)
{
for(i5=0;i5<=9;i5++)
{
multiplier = i1*10000+i2*1000+i3*100+i4*10+i5;
result = i5*100000+i5*10000+i5*1000+i5*100+i5*10+i5;
if(multiplier*i1==result)
{
printf("\n%5d%2d%2d%2d%2d\n",i1,i2,i3,i4,i5);
printf("X%12d\n",i1);
printf("_____________\n");
printf("%3d%2d%2d%2d%2d%2d\n",i5,i5,i5,i5,i5,i5);
}
}
}
}
}
}
getchar();
return 0;
}
枚举实例2:填运算符
例:5 5 5 5 5 = 5
注意:当填入除号时,要求右侧的数不为0;乘除的运算级别比加减高
#include<stdio.h>
int main(void)
{
int j,i[5];//循环变量,数组i表示四个运算符
int sign;//累加运算时的符号
int result;//式子运算结果
int count=0;//统计符合条件的方案
int num[6];//保存操作数
float left,right;//保存中间结果,用来解决运算符优先级 问题
char oper[5]={' ','+','-','*','/'};
printf("请输入5个数:");
for(j=1;j<=5;j++)
{
scanf("%d",&num[j]);
}
printf("请输入结果:");
scanf("%d",&result);
for(i[1]=1;i[1]<=4;i[1]++)//遍历第一个位置的运算符,1代表+号,2代表-号,3代表*号,4代表/号
{
if((i[1]<4 ) || (num[2]!=0)) //'/'号运算符的右侧数字不能问0
{
for(i[2]=1;i[2]<=4;i[2]++)//遍历第二个位置的运算符
{
if((i[2]<4 ) || (num[3]!=0))
{
for(i[3]=1;i[3]<=4;i[3]++)//遍历第三个位置的运算符
{
if((i[3]<4 ) || (num[4]!=0))
{
for(i[4]=1;i[4]<=4;i[4]++)//遍历第四个位置的运算符
{
if((i[4]<4 ) || (num[5]!=0))
{
/*四个位置的运算符都已确定,下面来确定运算结果*/
left=0;//假设第一个数右边为0,即0+第一个数
right=num[1];
sign=1;//即0+第一个数
for(j=1;j<=4;j++)
{
switch(oper[i[j]])
{
case '+':
left=left+sign*right;
sign=1;
right=num[j+1];
break;
case '-':
left=left+sign*right;
sign=-1;
right=num[j+1];
break;
case '*':
right=right*num[j+1];
break;
case '/':
right=right/num[j+1];
break;
}
}
if(left+sign*right==result)
{
count++;
printf("%3d: ",count);
for(j=1;j<=4;j++)
{
printf("%d%c",num[j],oper[i[j]]);
}
printf("%d=%d\n",num[5],result);
}
}
}
}
}
}
}
}
}
getchar();
return 0;
}
2.3递归算法
是一种直接或者间接调用自身的算法。
具体实现:一般通过函数或子过程来完成,在函数或子过程内部,编写代码直接或者间接调用自己,即完成递归操作
递归算法实例1:求阶乘
#include<stdio.h>
int factorial(int n);
int main(void)
{
int i;
printf("please input the number which you want to multiply: ");
scanf("%d",&i);
printf("the factorial result of 3 is: %d\n",i,factorial(i));
grtch();
return 0;
}
//recursive function
int factorial (int n)
{
if(n<=1)
return 1;
else
return n*factorial(n-1);//implement the call inside the function itself
}
递归算法实例2:数制转换
#include<stdio.h>
#include<string.h>
/*n is the number you want to convert,b is the radix you want to vonvert into*/
void conversion(char*s,int n,int b)
{
char bit[]={"0123456789ABCDEF"};
int len;
if(n==0)
{
strcpy(s,"");
return;//terminate the last recursive function ,will not execute the following statement of the function
}
/*verify the function of return
if(n==0)
{
printf("the resursion is over\n");
}
*/
conversion(s,n/b,b);
len = strlen(s);
s[len] = bit[n%b];
printf("the %d recursion\n",len) ;
s[len+1] ='\0';
}
int main(void)
{
char s[80];
int i,Decimal_num,radix;
printf("please input a decimal number: ");
scanf("%d",&Decimal_num);
printf("please input the radix: ");
scanf("%d",&radix);
conversion(s,Decimal_num,radix);
printf("%s\n",s);
getch();
return 0;
}