【 聲明:版權所有,歡迎轉載,請勿用於商業用途。 聯系信箱:feixiaoxing @163.com】
在數學中,有一些數據選擇的內容。舉個例子來說,有這樣一組數據:1、2、3、4。現在我們打算從中挑選出1個數據,那麼有幾種選擇呢?結果應該是1、2、3、4;那麼如果挑選2個數據呢,怎麼選呢?那麼結果應該是12、13、14、15。以此類推,我們還能挑選出3個數據、4個數據的情況。
那麼,在程序上面應該怎麼表示呢?其實可以使用遞歸的方法。請大家和我一起計算一下:
如果需要從1、2、3、4中挑選兩個數據,那麼是不是先從1開始,然後再2、3、4中挑選一個數據,這樣可以有12、13、14三種情況。接著呢,我們從2開始,下面可以選擇的數據只有從3、4中選擇了,1不能選擇了,否則會產生重復選項。以此類推,那我們從4開始的時候,發現4後面沒有數據的時候,此時迭代終止。
挑選2個數據如此,那麼挑選n個數據是不是也是這樣呢?首先選出第1個數據,那麼剩下來的數據只能從這個數據後面位置開始挑選,如果挑選出n-1個數據,那麼表示n個數據存在,繼續尋找到,直到n-1個數據選不出來為止;接著我們移動第一個數據的位置,同樣需要在當前數據的後面挑選n-1個數據。以此類推,如果我們發現當前數據後面連n-1個數據都沒有了,那麼表示遞歸就結束了。
下面我們就可以書寫代碼了。
a) 定義全局空間和打印函數,保存已經遍歷的數據
static int gAllData[MAX_NUMBER]= {0};
static int gTotal = 0;
void print(int pData[], int length)
{
int index;
for(index = 0; index < length; index++)
printf("%d", pData[index]);
printf("\n");
}
static int gAllData[MAX_NUMBER]= {0};
static int gTotal = 0;
void print(int pData[], int length)
{
int index;
for(index = 0; index < length; index++)
printf("%d", pData[index]);
printf("\n");
} b)開始數據的迭代
void traverse(int pData[], int length, int number)
{
int index;
if(0 == length)
return;
for(index = 0; index < length; index++){
gAllData[gTotal ++] = pData[index];
if(1 == number)
print(gAllData, gTotal);
else
traverse(pData + (index + 1), length - (index + 1), number -1);
gAllData[-- gTotal] = 0;
}
}
void traverse(int pData[], int length, int number)
{
int index;
if(0 == length)
return;
for(index = 0; index < length; index++){
gAllData[gTotal ++] = pData[index];
if(1 == number)
print(gAllData, gTotal);
else
traverse(pData + (index + 1), length - (index + 1), number -1);
gAllData[-- gTotal] = 0;
}
} c)編寫測試用例,驗證結果
void test()
{
int data[] = {1, 2, 3, 4, 5, 6};
memset(gAllData, 0, sizeof(int) * MAX_NUMBER);
traverse(data, sizeof(data)/sizeof(int), 4);
}
void test()
{
int data[] = {1, 2, 3, 4, 5, 6};
memset(gAllData, 0, sizeof(int) * MAX_NUMBER);
traverse(data, sizeof(data)/sizeof(int), 4);
}
注:我們可以通過不停修改數組data和數值number的方法,驗證打印出來的數據和我們自己計算的結果是否有出入。