C問題---典型遞歸問題

---------------------------------
典型例題 31:C問題---典型遞歸問題
---------------------------------
(1)輸入兩個字符串, 比如abdbcc和abc, 輸出第二個字符串在第一個字符串中的連接次序。
即輸出:125,126,145,146。
答案:
  1    #include <iostream>
  2    #include <cstdio>
  3    #include <cstring>
  4     
  5    using namespace std;
  6     
  7    void PrintfArrary(char *p_str,char *s_str,int *print_arr,/
  8                      int p_len, int s_len,int print_arr_num,/
  9                      int p_start_num,int s_start_num)
 10    {
 11        int pStartnum = p_start_num, sStartnum = s_start_num;
 12        int printNum = print_arr_num;
 13     
 14        if (printNum == s_len)
 15            {
 16                for (int i= 0; i < s_len;i++)
 17                    {
 18                        cout<<*(print_arr+i);
 19                        cout<<" ";
 20                    }
 21                cout<<endl;
 22                return;
 23            }
 24     
 25        for (int i = sStartnum; i < s_len ; i++)
 26            {
 27                for (int j= pStartnum; j < p_len; j++)
 28                    {
 29                        if (*(p_str+j) == *(s_str+i))
 30                            {
 31                                print_arr[printNum] = j+1;
 32                                pStartnum = j;
 33                                sStartnum = i;
 34                                PrintfArrary(p_str,s_str,print_arr,p_len,s_len,printNum+1,pStartnum+1,sStartnum+1);
 35                            }
 36                    }
 37            }
 38     
 39    }
 40     
 41     
 42    void ConnectSequence(char *p_str,char *s_str)
 43    {
 44        int p_len = strlen(p_str);
 45        int s_len = strlen(s_str);
 46        int *print_arr = new int[s_len];
 47        unsigned int print_arr_num = 0;
 48     
 49        if (NULL == p_str && NULL == s_str)
 50            {
 51                cout<<"string erro" <<endl;
 52                return;
 53            }
 54     
 55        if (NULL == print_arr)
 56            {
 57                cout<<"allocate error" <<endl;
 58                return;
 59            }
 60     
 61     
 62        PrintfArrary(p_str,s_str,print_arr,p_len,s_len,print_arr_num,0,0);
 63     
 64     
 65    }
 66     
 67    int main()
 68    {
 69        char ParString[]="abdbcc";
 70        char SonString[]="abc";
 71        ConnectSequence(ParString,SonString);
 72        return 0;
 73    }
-----------
結果:
$ ./a.out
1 2 5
1 2 6
1 4 5
1 4 6
-----------
知識點:遞歸與回溯
    1)思路:
先找到第二個字符串中各個字符分別出現的位置。利用其位置構造多叉樹(構造規則爲子節點必須比父節點大)。 遍歷構造完成的多叉樹即是相應的組合。
分析:
例子中:abdbcc, abc
搜索得到a,b,c在源字符串中出現位置序列分別爲{1},{2,4},{5,6}
那麼以第一個序列爲基礎,開始構造多叉樹。
  1
 2  4 //在第二個序列中取值
5 6 5 6 //在第三個序列中取值
然後多叉樹的每一個分支就是一種有效組合

s_str->[a][b][c](i)
p_str->[a][b][d][b][c][c](j)
    [0][1][2][3][4][5]
i=0,j=0 [1][ ][ ](a==a ,1(j+1)push into print_arr)
i=1,j=1 [1][2][ ](b==b,2)
i=2,j=2 [1][2][ ](c!=d)
i=2,j=3
i=2,j=4 [1][2][5](c==c,5)
下一次遞歸,打印1 2 5,return;
i=2,j=5 [1][2][6](c==c,6)
下一次遞歸,打印1 2 6,return;
i=3,j=6 return;
i=1,j=2
i=1,j=3 [1][2][ ](b==b,4)
......
    (2)i ,j 兩個循環的位置可以互換,但是依據並行算法規則小循環在外,大循環在內效率要高!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章