---------------------------------
典型例题 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 两个循环的位置可以互换,但是依据并行算法规则小循环在外,大循环在内效率要高!