1. 程式人生 > >一箇中興的面試題,輸入兩個數n和m,從數列1,2,3……n中隨意取幾個數,使其和等於m,要求將其中所有組合列出來程式設計求解(c語言遞迴函式分解法)

一箇中興的面試題,輸入兩個數n和m,從數列1,2,3……n中隨意取幾個數,使其和等於m,要求將其中所有組合列出來程式設計求解(c語言遞迴函式分解法)

原題目:輸入兩個數n和m,從數列1,2,3……n中隨意取幾個數,使其和等於m,要求將其中所有組合列出來程式設計求解

c語言解法分析:

           先判定n和m的大小,如果m小於n,則只需從1,2……m之間找出和為m的組合即可,如果m大於n,則需要判斷1~n的和是否大於或等於m,否則引數無效,當組合滿足以上有效條件,先判定1~n中連續相加的和大於等於m時即可得出該組合的最多項,並用遞迴演算法實現組合項操作,最小組合項為2;程式碼實現如下:

#include <stdio.h>
#include <stdlib.h>
static int end=0;
static int step=0;
static int flag_mem=0;
static int sum_m=0;
static int *arry_p = NULL;
int sum_run;
int run_pr;
int i_sum=0;
void sum_fun(int count,int from) //遞迴方法求組合
{ 
   
 if(flag_mem)
    arry_p = (int *)malloc(step*sizeof(int));
    flag_mem=0;
 if(count == step) 
 { 
        run_pr=count;
  for(sum_run=0;count >= 1; count--)
        { 
            sum_run += *(arry_p+step-count);
        }
        if(sum_run==sum_m){
        for(;run_pr >= 1; run_pr--)
        { 
            printf("%d",*(arry_p+step-run_pr));
   if(run_pr >= 2)
    printf(" + ");
        }
  printf(" = %d",sum_m);
        printf("\n"); 
        i_sum++;
        }
  
  return ; 
 } 
 for(;step - count <= end - from ; from++) 
 {
   *(arry_p+count) = from + 1;
   sum_fun(count+1,from+1); 
 } 
}
int n_sum(int m)
{
 int i,sum;
    for(sum=0,i=1;sum <= m; i++)
  sum += i;
    i--;    
    return i;
}
int main(void) 
{
 int n,m,sum;
    int i,j;
 printf("請輸入兩個數m和n,求1~n中加起來和為m的組合: n =");
 scanf("%d",&n);
 printf("m = ");
 scanf("%d",&m);
    sum = (1+n)*n/2;
 if(n<m){
  if(sum < m){
   printf("該組合不存在 \n");
        }else if(sum == m){
   for(i = 1;i <= n; i++)
    printf("%d ", i);
   printf("\n");
        }else
        {
   end = n;
            sum_m = m;
   for(i=n_sum(m);i>=2;i--)
            {
    step = i;
                flag_mem = 1;
               sum_fun(0,0);
                free(arry_p);  
            }
        }   
    }else 
    {
  if(m <= 2){
   printf("該組合不存在 \n");
        }else{
   end = m;
            sum_m = m;
            for(i=n_sum(m);i>=2;i--)
            {
    step = i;
                flag_mem = 1;
               sum_fun(0,0);
                free(arry_p);  
            }
        }
    }
 printf("總共有 %d 套組合 \n",i_sum);
    i_sum = 0;
 system("pause");
 return 0;
}
執行結果如下:

如果大家有興趣可以試試大的資料,我曾經試過從1~33中列印加起來為150的組合,有4040970種,呵呵,如果有人感興趣可以試試,就要看各位朋友計算機效能了!

注:初次發表文章,請多多關照,因能力有限,如有錯誤請及時反饋,謝謝!