用递归算法求和为指定值N的所有组合



/*
 CSDN上最近常常问到这样上面的问题,例如,求所有和为10的组合(组合中的数皆为自然数,且各不相同)
*/
#include 
" stdio.h "
#include 
" conio.h "

#define  N 10

int  num[N];

main()
{
    searchJoinNum(
1 ,N, 0 );  /* 调用递归函数 */

    getch();
}


/*
_minNum: 最小的被加的数
_sumLeave: 和的剩余值
_arrCurBound: 存放被加的数的数组当前下标?
*/
searchJoinNum(
int  _minNum, int  _sumLeave, int  _arrCurBound)
{
    
int  minNum = _minNum;
    
int  sumLeave = _sumLeave;
    
int  arrCurBound = _arrCurBound;
    
int  i,j = arrCurBound,temp;

    
if (sumLeave == 0 /* 多次减后被减光 */
    {
       output(num); 
/* 输出数组,数组元素中不是 NULL 的元素被输出 */

       num[arrCurBound
- 1 ] = NULL;  /* 清空上次给数组赋的值,返回到上次递归 */
       
return ;
    }

    
if (sumLeave < minNum)  /* 不够减时,清空上次给数组赋的值,返回到上次递归 */
    {
        num[arrCurBound
- 1 ] = NULL;
        
return ;
    }

    
for (i = minNum;i < N;i ++ )
    {
       temp
= sumLeave;  /* 在循环中保留现场 */

       num[j]
= i;
       sumLeave
-= i;

       searchJoinNum(i
+ 1 ,sumLeave,j + 1 );  /* 在循环中调用递归,参数特点:被加的数字依次增大 */

       sumLeave
= temp;  /* 返回现场 */
    }

}

output(
int  _num[N])
{
    
int  i;

    printf(
" %d= " ,N);
    
for (i = 0 ;i < N;i ++ )
    {
       
if (_num[i] == NULL) break ;
       
if (i != 0 )
       {
           printf(
" + " );
       }
       printf(
" %d " ,_num[i]);
    }
    printf(
" \n " );
}

你可能感兴趣的:(算法)