1. 程式人生 > >整數劃分的非遞迴演算法(C語言)

整數劃分的非遞迴演算法(C語言)

記錄點滴成長:

整數劃分的非遞迴演算法

例如將整數6劃分為如下:

6
5 1
4 2

4 1 1
3 3

3 2 1

3 1 1 1
2 2 2

2 2 1 1

2 1 1 1 1
1 1 1 1 1 1
如6有11個劃分。

#include "stdio.h"
void  Divinteger(int n)
{
 if (n==1) //處理輸入值為1的情況,因為如果輸入1,就不用再劃分
 { 
  printf("只有一種劃分:1/n");
  return;
 }

 if (n == 2) //處理輸入值為2 的情況,如果輸入為2,只要寫成1+1就可以了。
 {
 printf("第1種劃分:2/n");
 printf("第2種劃分:1 1/n");
 printf("一共有2種劃分!/n");
 return;
 }

 int *a =new int(n); //定義動態陣列,因為當n大於2時,如3=2+1,這時就需要對2進行相似劃分,其大小是不固定的,因而用動態陣列。
 int div=0; //每一行劃分的陣列下標
 int k=1;//記錄種類的值。
 a[0] = n - 1;
 a[1] = 1;
 div = 2; //第二次一定劃分為2個值。n-1和1

 printf("第%2d種劃分:%d /n",1,n);
 int i;
 do{
  k++;
  printf("第%2d種劃分:",k);
  printf("%d", a[0]);
  for (i = 1; i < div; i++)
   printf("  %d", a[i]);
  printf("/n");


 int s = 0;
 
 do{
  s += a[--div];
 }while (div >= 0 && a[div] == 1); //這裡用來找到非1的可以繼續劃分的值,如5 1,通過這一部找到5;
 if (div == -1)
  break; 

 int d = a[div] - 1; //判斷是否還有數字可以繼續劃分。
 if (d == 1) //這句戶用來為下一個迴圈做準備,
 {
  while (s > 0) //s存放著下一行一共有幾個值
  {
  a[div++] = 1; //將下一行的值全部賦值為1.等待下一個迴圈輸出。
  s--;
  }
 }
 else //表示還有值可以繼續劃分
 {
  do{
   a[div++] = d;// 相當於向右移動一位,進入下一次劃分(對4)
   s -= d;
  }while (s >= d); //得出a[0]=4 
  if (s != 0)
  a[div++] = s; //得出a[1]=2    div=2
 }
 
 }while (1);
 
 printf("/n一共有 %d 種方法!/n/n",k);
}

void main()
{
 int n;
 printf("輸入你要求的劃分整數值:/n");//輸入n值
 scanf("%d", &n);

 Divinteger(n); //呼叫劃分函式
}