1717*
1818*
1919**********************************************************************************/
20-
20+ #include < stdlib.h>
21+ #include < time.h>
2122#include < string.h>
2223#include < iostream>
2324#include < string>
2425#include < map>
2526#include < vector>
2627using namespace std ;
2728
29+ // =====================
30+ // Dynamic Programming
31+ // =====================
32+ //
33+ // The idea as below:
34+ //
35+ // Considering m[i][j] means the distance from T[i] to S[j], and add the empty "" case, then,
36+ //
37+ // A) Initialization for empty case: m[0][j] = 1;
38+ //
39+ // B) Calculation
40+ //
41+ // a) Target-len > Source-len cannot found any substring
42+ // i > j : m[i][j] = 0;
43+ //
44+ // b) if not equal, take the value of T[i] => S[j-1] (e.g. ["ra" => "rabb"] =["ra" => "rab"] )
45+ // S[j] != T[i] : m[i][j] = m[i][j-1]
46+ //
47+ // c) if equal. (e.g. ["rab" => "rabb"] = ["rab" =>"rab"] + ["ra" => "rab"] )
48+ // S[j] == T[i] : m[i][j] = m[i][j-1] + m[i-1][j-1]
49+ //
50+ // 1) Initialize a table as below
51+ // "" r a b b b i t
52+ // "" 1 1 1 1 1 1 1 1
53+ // r
54+ // b
55+ // t
56+ //
57+ // 2) Calculation
58+ // "" r a b b b i t
59+ // "" 1 1 1 1 1 1 1 1
60+ // r 0 1 1 1 1 1 1 1
61+ // b 0 0 0 1 2 3 3 3
62+ // t 0 0 0 0 0 0 0 3
63+ //
64+ int numDistinct1 (string S, string T) {
65+ vector< vector<int > > m (T.size ()+1 , vector<int >(S.size ()+1 ));
66+
67+ for (int i=0 ; i<m.size (); i++){
68+ for (int j=0 ; j<m[i].size (); j++){
69+
70+ if (i==0 ){
71+ m[i][j] = 1 ;
72+ continue ;
73+ }
74+ if ( i>j ) {
75+ m[i][j] = 0 ;
76+ continue ;
77+ }
78+ if (S[j-1 ] == T[i-1 ]){
79+ m[i][j] = m[i][j-1 ] + m[i-1 ][j-1 ];
80+ } else {
81+ m[i][j] = m[i][j-1 ] ;
82+ }
83+ }
84+ }
85+ return m[T.size ()][S.size ()];
86+ }
2887
29- // Dynamic Programming
30- int numDistinct (string S, string T) {
88+
89+ // =====================
90+ // Dynamic Programming
91+ // =====================
92+ //
93+ // The idea here is an optimization of above idea
94+ // (It might be difficult to understand if you don't know the above idea)
95+ //
96+ // For example:
97+ //
98+ // S = "abbbc" T="abb"
99+ // posMap = { [a]={0}, [b]={1,2} }
100+ // numOfSubSeq = {1, 0, 0, 0 }
101+ //
102+ // S[0] is 'a', pos is 0, numOfSubSeq = {1, 0+1, 0, 0};
103+ //
104+ // S[1] is 'b', pos is 2, numOfSubSeq = {1, 1, 0, 0+0};
105+ // pos is 1, numOfSubSeq = {1, 1, 0+1, 0};
106+ //
107+ // S[2] is 'b', pos is 2, numOfSubSeq = {1, 1, 1, 0+1};
108+ // pos is 1, numOfSubSeq = {1, 1, 1+1, 1};
109+ //
110+ // S[3] is 'b', pos is 2, numOfSubSeq = {1, 1, 2, 2+1};
111+ // pos is 1, numOfSubSeq = {1, 1, 1+2, 3};
112+ //
113+ // S[4] is 'c', not found, numOfSubSeq = {1, 1, 3, 3};
114+ //
115+ //
116+ int numDistinct2 (string S, string T) {
31117
32118 map< char , vector<int > > pos_map;
33119 int len = T.size ();
34- int *numOfSubSeq = new int [len+1 ];
35- memset (numOfSubSeq, 0 , sizeof (int ) * (len+1 ) );
120+ vector<int > numOfSubSeq (len+1 );
36121 numOfSubSeq[0 ] = 1 ;
37122
38123 for (int i=len-1 ; i>=0 ; i--){
39124 pos_map[T[i]].push_back (i);
40125 }
41-
42126
43127 for (int i=0 ; i<S.size (); i++){
44128 char ch = S[i];
@@ -50,11 +134,22 @@ int numDistinct(string S, string T) {
50134 }
51135 }
52136
53- int result = numOfSubSeq[len];
54- delete[] numOfSubSeq;
55- return result;
137+ return numOfSubSeq[len];
56138}
57139
140+
141+ // random invoker
142+ int numDistinct (string S, string T) {
143+ srand (time (0 ));
144+ if (rand ()%2 ){
145+ cout << " -----Dynamic Programming Method One-----" << endl;
146+ return numDistinct1 (S,T);
147+ }
148+ cout << " -----Dynamic Programming Method Two-----" << endl;
149+ return numDistinct2 (S,T);
150+ }
151+
152+
58153int main (int argc, char ** argv)
59154{
60155 string s = " rabbbit" ;
0 commit comments