<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Feng.Li's Java See

    抓緊時(shí)間,大步向前。
    隨筆 - 95, 文章 - 4, 評(píng)論 - 58, 引用 - 0
    數(shù)據(jù)加載中……

    遞歸求解問(wèn)題的通用方法

    程序設(shè)計(jì)中遞歸不失為一種優(yōu)雅的方法,可以用簡(jiǎn)單的代碼解決看似復(fù)雜的問(wèn)題。本文闡述了如何使用遞歸程序來(lái)解決一系列復(fù)雜的問(wèn)題,并對(duì)遞歸程序的執(zhí)行原理以及通用求解問(wèn)題的方法作出了分析

    編寫遞歸程序有幾個(gè)重要的原則,細(xì)節(jié)詳敘如后。
        1. 要解決的問(wèn)題可拆分為幾個(gè)與原問(wèn)題類似的子問(wèn)題(子問(wèn)題仍可拆分)。
        2. 每個(gè)子問(wèn)題必須比原來(lái)問(wèn)題的規(guī)模更小(即使小一號(hào)也行,當(dāng)然如果能夠迅速減小規(guī)模更好)。
        3. 遇到足夠小的子問(wèn)題時(shí)就直接解決之,防止問(wèn)題無(wú)限細(xì)分下去,也就是防止無(wú)限遞歸(遞歸終止條件很重要)。 
    先看一個(gè)最簡(jiǎn)單的遞歸程序,下面程序求整數(shù)n的階乘:
    int factorial(int n)
    {
        return n <= 1 ? 1 : n*factorial(n-1);
    }
    所謂遞歸程序,就是程序在執(zhí)行中又調(diào)用其自身,如上面函數(shù)factorial在其函數(shù)體內(nèi)調(diào)用了函數(shù)factorial。函數(shù)在每次被調(diào)用時(shí)都會(huì)生成一個(gè)包含自身局部變量的副本,即算是函數(shù)調(diào)用自身時(shí)也是如此。
    遞歸程序主體主要由兩部分構(gòu)成:一是遞歸執(zhí)行部分,包含遞歸執(zhí)行所需的條件;一是遞歸終止部分,含遞歸終止條件。上面求階乘的程序中把這兩部分寫在一行代碼里面,把其分別抽出來(lái)便是:
    int factorial(int n)
    {
        if(n <= 1) return 1;     // 遞歸終止體
        return n*factorial(n-1); // 遞歸執(zhí)行體

    }


    下面以幾個(gè)經(jīng)典算法問(wèn)題的遞歸程序求解為例來(lái)分析編寫遞歸程序中可以遵循的簡(jiǎn)單規(guī)則。
    1. 求正整數(shù)n所有可能的和式的組合,如給定正整數(shù)3,所有和加起來(lái)等于3的和式如下:
    3 = 3 + 0
    3 = 2 + 1
    3 = 1 + 1 + 1
    其中一個(gè)和式中的因子只能為自然數(shù),因子允許重復(fù)出現(xiàn)。

    這個(gè)問(wèn)題是一個(gè)組合問(wèn)題的變形,用遞歸程序?qū)崿F(xiàn)如下(分析見(jiàn)注釋):
    #define MAXSIZE 50       
    static int buff[MAXSIZE]; // 存儲(chǔ)和式因子組合的緩沖
    /// 求當(dāng)前和式中因子之和。
    int Sum(int buff[],int i)
    {
        int sum = 0;
        for(int m=0; m<=i; m++)
            sum += buff[m];
        return sum;
    }
    /// 打印當(dāng)前滿足條件的和式。
    void printFactor(int buff[],int i,const int number)
    {
        int count = 0, m;
        for(m=0; m<=i; m++)
            printf("%4d",buff[m]);
        if(number==buff[0])
            printf("%4d",0);
        printf("\n");
    }
    /// 遞歸求解所有和式組合。
    /// i - 當(dāng)前可選自然數(shù)的最大值。
    /// top - 當(dāng)前組合中因子個(gè)數(shù)。
    /// number - 問(wèn)題中要求解和式的正整數(shù)。
    void divide(int i,int top,int number)
    {   
        for(int j=i; j>0; j--)               // 注意這里的循環(huán)條件,可以有效防止出現(xiàn)重復(fù)的組合
        {
            buff[top ] = j;

            if(number == Sum(buff,top))      // 首先要確定遞歸中止條件
                printFactor(buff,top,number);
            else if(number < Sum(buff,top))  // 繼續(xù)增加和式中的因子
                continue;

            if(top >= number)                // 和式中的因子不應(yīng)該超過(guò)和的大小
                continue;

            divide(j,top+1,number);          // 減小問(wèn)題規(guī)模,繼續(xù)遞歸
        }
        return;
    }

    int main()
    {
        int i,top = 0;
        int number = 8;
        printf("input a souce number:");
        scanf("%d",&number);
        i = number;
        divide(i,top,number);

        return 0;
    }

    2. 給定正整數(shù)k,以及1-k共 k個(gè)正整數(shù)的一個(gè)排列,假如是 1,2,3,...,k,求所有和此排列“不相交”的排列。
    所謂不相交,是指新的排列和已有排列在同一位置上的數(shù)都不相同。如假設(shè)k=3,則其排列:
    1 2 3 和 3 2 1是相交的,因?yàn)榈诙€(gè)位置上都是2;而排列1 2 3 和 3 1 2則不相交。

    問(wèn)題分析:此問(wèn)題是普通排列問(wèn)題的變形,只要在排列問(wèn)題的遞歸程序中加上位置的限制即可,程序?qū)崿F(xiàn)如下,具體分析見(jiàn)注釋

    posted on 2007-12-26 20:04 小鋒 閱讀(686) 評(píng)論(0)  編輯  收藏 所屬分類: algorithm

    主站蜘蛛池模板: 99re6在线精品免费观看| 成人无遮挡毛片免费看| 亚洲大片免费观看| 女人18毛片a级毛片免费| av电影在线免费看| 大地资源网高清在线观看免费| 亚洲成AV人片在线观看| AV片在线观看免费| 亚洲黄片手机免费观看| 亚洲第一页在线播放| 免费一级做a爰片性色毛片| 爱丫爱丫影院在线观看免费 | 亚洲国产精品综合久久20| 亚洲av无码乱码在线观看野外 | 久久99精品国产免费观看| 亚洲自偷自偷在线成人网站传媒| 亚洲国产一成久久精品国产成人综合 | 亚洲动漫精品无码av天堂| 成人a视频片在线观看免费| 97在线免费视频| 亚洲精品国产综合久久久久紧| 亚洲美女免费视频| 亚洲成A∨人片在线观看无码| 国产zzjjzzjj视频全免费| 8x成人永久免费视频| 三级片免费观看久久| 亚洲中文无码av永久| 亚洲日韩乱码中文无码蜜桃臀网站| 成人影片麻豆国产影片免费观看 | 成人免费观看男女羞羞视频| 亚洲国产精品xo在线观看| 成年人免费观看视频网站| a毛片免费播放全部完整| 亚洲AV成人片无码网站| 内射少妇36P亚洲区| 国内精品99亚洲免费高清| 国产精品国产免费无码专区不卡 | 免费无码又爽又高潮视频| 亚洲精品成人无限看| 国产极品美女高潮抽搐免费网站| 99re6在线精品视频免费播放|