问答题
[说明]
本程序的函数sum(int i int total, int sigma, int rear, int d[], int n)用来从已知数组d的前n个元素中找出所有部分元素序列之和等于total的元素序列,约定数组d的元素都是正整数,且都小于等于total。
函数sum使用递归方法找出全部解答。参数i表示递归函数当前考虑元素d[i],参数sigma是调用前已选取的部分序列的元素和,参数rear是后面还未考虑的那部分元素的元素和。
函数对元素d[i]有以下两种可能的选择方案。
(1)考虑元素d[i]被包含在新的部分元素序列中的可能性。如果在当前部分元素序列之后接上d[i],新序列的元素和不超过total,则函数将d[i]包含在当前部分元素序列中。如果新的部分元素序列的元素和等于total,新的部分元素序列就是一个解答,函数将其输出;否则,若继续考虑后面的元素还有可能找到解答时,函数就递归去考虑后面的元素,寻找解答。最后,函数应恢复原来部分元素序列中不包含d[i]的状态。
(2)考虑元素d[i]不被包含在新的部分元素序列中的可能性。如果继续向d[i]之后考虑还是有希望能得到和为total的部分元素序列时,函数将新序列(不包含d[i])也作为一种可能的选择,并递归去考虑后面的元素,寻找解答。
[C程序]
#include <stdio. h>
#define N 100
int a[N];
int flg[N];
sum (int i, int total, int sigma, int rear, int d[], int t)
{
int j;
/* 考虑元素d[i]被包含在新的部分元素序列中的可能性 */
if (sigma + d[i] <=total) { /*如果d[i]与当前序列的和不超过total*/
flg[i]=1;/* d[i]被考虑在部分元素序列中 */
if (______=total) { /* 输出解 */
for (j=0; flg[j] == 0; j++) printf ("%4d = %d", total,d[j]);
for (j++; j <=i; j++) {
if (flg[j]) printf ("+%d", d[j]);
}
printf("");
} else if(i <n-1 && rear+sigma >=total)
/* 并且继续考虑后面的元素有可能找到解答时 */
sum (i+1, total, ______, rear-d[i], d, n);
______;
/* 考虑元素d[i]不被包含在新的部分元素序列中的可能性*/
if (i <n-1 && rear-d[i]+tigma >=total)
sum(i+1, total, ______, rear-d[i], d, n);
}
}
main()
{
int i, j, n, total, s, d;
printf ("输入 total! /n"); scanf ("%d", &total);
printf ("输入 n! /n"); scanf ("%d", &n);
for (s = i = 0; i < n;) {
printf ("输入第%d个元素 > 0 且 <= %d)\n", i+1, total);
scanf ("%d", &d);
if (d < 1 || d > total) {
printf ("出错, 清重新输入! \n");
continue;
}
s+=(a[i++]=d);
}
sum (0, total, 0, ______, a, n);
printf ("\n\n");
}