当前位置:嗨网首页>书籍在线阅读

16-和式分解

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

12.2.4 和式分解

问题描述

19.png 实现一个递归函数,要求给定一个正整数i,输出和为i的所有非递增的正整数和式。例如,若i=5,则输出的和式结果如下。

5=5
5=4+1
5=3+2
5=3+1+1
5=2+2+1
5=2+1+1+1
5=1+1+1+1+1

【分析】

这是2009年中国人民银行考研的笔试题目。引入数组a,用来存放分解出来的和数。其中,a[k]存放第k步分解出来的和数。递归函数应设置3个参数:第1个参数是数组名a,用来将数组中的元素传递给被调用函数;第2个参数(i)表示本次递归调用要分解的数;第3个参数(k)是本次递归调用将要分解出的第k个和数。递归函数的原型如下。

 void rd(int a[],int i,int k)

对将要分解的数i,可分解出的和数j共有i种可能,它们是i, i−1,…, 2, 1。但为了保证分解出来的和数依次构成不增的正整数序列,要求从i分解出来的和数j不能超过a[k−1],即上次分解出来的和数。

特别地,为保证对第一步(k=1)的分解也成立,算法可在a[0]预置n,即第一个和数最大为n。在分解过程中,当分解出来的和数j等于i时,说明已完成一个和式分解,应将和式输出;当分解出来的和数j<i时,说明还有i−j需要进行第k+1次分解。

第12章\实例12-13.c
/********************************************
*实例说明:和式分解
*********************************************/
1  #include<stdio.h>
2  #define N 50
3  void rd(int a[],int i,int k);
4  void main()
5  {
6      int n,a[N];
7      printf("请输入一个正整数n(0<=n<50):");
8      scanf("%d",&n);
9      a[0]=n;
10     printf("和式分解结果:\n");
11     rd(a,n,1);
12 }
13 void rd(int a[],int i,int k)
14 {
15     int j,p;
16     for(j=i;j>=1;j--)
17     {
18         if(j<=a[k-1])
19         {
20            a[k]=j;
21            if(j==i)
22            {
23               printf("%d=%d",a[0],a[1]);
24               for(p=2;p<=k;p++)
25                   printf("+%d",a[p]);
26               printf("\n");
27            }
28            else
29               rd(a,i-j,k+1);
30        }
31     }
32 }

运行结果如图12.17所示。

364.png

图12.17 运行结果

【说明】

第16行中,循环语句表示待分解的数的范围为从i到1。

第18行中,表示如果当前待分解的和数j小于已经分解的和数a[k−1],这是为了保证分解出的和数按照不增的顺序排列。

第20行中,将当前的待分解的和数j存放到序号为k的数组位置。

第21~27行中,如果j等于i,则表示已完成一个和式分解,输出该和式。

第28~29行中,将还未分解的数i−j和分解的和数次数k传递给rd函数进行递归调用求解。