递推法

递推法分析

能采用递推法的问题具有如下重要性质:即当得到问题规模为i-1的解后,由问题的递推性质,能构造出问题规模为i的解。这样,程序可以从i=0i=1出发,重复的,由已知至i-1规模的解,通过递推,获得规模为i的解,直至得到规模为N的解。

例:编写程序,对给定的n(n<=100),计算并输出k的阶乘k!(k=1, 2, ……, n)的全部有效数字。

由于要求的整数可能大大超出一般整数的位数,程序用一维数组存储长整数,存储长整数数组的每一个元素只存储长整数的一位数字。如有m位长整数N用数组a[]存储:

 

N=a[m]×10m-1+ a[m-1]×10m-2+……+ a[2]×101+ a[1]×100

 

 

并用a[0]存储长整数N的位数m,即a[0]=m。按上述约定,数组的每个元素存储k的阶乘k!的一位数字,并从低位到高位依次存于数组的第二元素、第三元素……例如,5!=120,在数组中的存储形式为:

 

3

0

2

1

……

 

首元素3表示长整数是一个3位数,接着是低位到高位依次是021,表示长整数是120.

计算阶乘k!可采用对以求得的阶乘(k-1)!连续累加k-1次后求出。例如,4!=24,计算5!,可对原来的24再累加424后得到120.

C语言实现代码:

#include<stdio.h>
#include<malloc.h>

#define MAXN 1000

void recursion(int a[], int k)
{
 //已知a中的(k-1)!,求出k!(k<1000)
 int * b;
 int m=a[0];
 b=(int *)malloc(MAXN * sizeof(int));
 for(int i=1; i<=m; i++)
 {
  b[i]=a[i];
 }
 for(int j=1; j<k; j++)
 {
  //控制累加k-1次
  int carry=0;
  int r;
  for(int i=1; i<=m; i++)
  {
   r=a[i]+b[i]+carry;
   a[i]=r%10;
   carry=r/10;
  }
  if(carry)
  {
   m++;
   a[m]=carry;
   b[m]=0;
  }
 }
 free(b);
 a[0]=m;
}

void write(int * a, int k)
{
 printf("%4d! = ", k);
 for(int i=a[0]; i>0; i--)
 {
  printf("%d", a[i]);
 }
 printf("/n");
}

void main()
{
 int a[MAXN];
 a[0]=1;
 a[1]=1;
 int n;
 printf("Enter the number:");
 scanf("%d", &n);
 write(a, 1);
 for(int k=2; k<=n; k++)
 {
  recursion(a, k);
  write(a, k);
 }
}

 

递推法总结

  递推法是一种简单有效的方法,一般用这种方法编写的程序执行效率很高,可以解决具有前效相关性,且前效相关性顺序确定、个数不多、个数为定数的问题。

  递推法和递归法的关系:任何可以用递推法解决的问题,都可以很方便的利用递归法解决;但是,并非所有能用递归法解决的问题都能用递推法解决。这是因为,递归法利用的递归工作栈,可以为任意长度和顺序的前效相关性。

 

  程序编译正确,运行过程中出现错误:DAMAGE:after Normal block (#45) at 0x003707AB。在csdn上找到原因:断点调试发现前面都可以通过,只要走到释放内存的free处,程序就会挂掉,后来发现是内存访问越界,针对该程序而言是使用malloc申请的空间过小,编译器傻不拉叽的往前走,读写都可以正确得到结果,直到free的时候编译器才发现问题,于是就崩掉了。

 

  用malloc分配的内存空间,如果越界,free时就会产生这样的错误。今天无意发现了一个牛人的博客,呵呵,高兴!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值