在某本软考的书上,有一个关于算法中回溯法的案例,是求子集和的问题。即从指定的一组数中,找到所有和等于某个特定值的所有组合。C语言代码如下(我的注释部分利用了【重量】的概念,...
在某本软考的书上,有一个关于算法中回溯法的案例,是求子集和的问题。即从指定的一组数中,找到所有和等于某个特定值的所有组合。C语言代码如下(我的注释部分利用了【重量】的概念,因为我习惯把它理解为背包问题,实际就是值),我搞C#和Java搞习惯了,这个代码我设置了断点也搞不懂它怎么实现递归和实现终结的,虽然程序说明中说条件已经规定了其递归条件,但是为什么它会自动递归和终结???:
#include
#define MAX 100
int w[MAX],slcted[MAX],m,n;
void sumofsub(float curSum,int k,float totalSum)
{
int i;
slcted[k]=1;
if(curSum+w[k]==m) //找到一个解 输出,很奇怪,程序为什么在此没有结束,会继续查找其他解
{
for(i=1;i<=k;i++) printf("%4d(%-2d)",slcted[i],w[i]);
printf("\n");
}
else
{
if(curSum+w[k]+w[k+1]<=m) //w[k]包含在解向量中是否可行
sumofsub(curSum+w[k],k+1,totalSum-w[k]); //可行则夸大规模,并从【总重量】中减去【当前物品】
if(curSum+totalSum-w[k]>=m && curSum+w[k+1]<=m) //当【剩下的重量】可以填满【目标重量】 && 下一个物品足够小时
{
slcted[k]=0; //可行则扩大规模
sumofsub(curSum,k+1,totalSum-w[k]);
}
}
}
void main()
{
int i;//,k
float totalSum,curSum;
totalSum=curSum=0;
//k=1;
for(i=0;i<=MAX;i++) slcted[i]=0; //初始化选择索引
printf("请输入n的值:\n");
scanf("%4d",&n); //n为总集合个数
printf("请输入目标和的值:\n");
scanf("%4d",&m); //m为目标和
printf("请按升序输入数组w的各个元素:\n");
for(i=1;i<=n;i++) scanf("%4d",&w[i]);
for(i=1;i<=n;i++)
totalSum+=w[i]; //r初始化为总集合的总和
printf("选择情况:\n");
sumofsub(curSum,1,totalSum);
main();
}
展开