1
+
2
+ #include < bits/stdc++.h>
3
+ using namespace std ;
4
+ typedef struct node
5
+ {
6
+ node *children[26 ];
7
+ bool isEOW;
8
+ } node;
9
+ node *createNode ()
10
+ {
11
+ node *newNode = (node *)malloc (sizeof (node));
12
+ for (int i = 0 ; i < 26 ; i++)
13
+ newNode->children [i] = NULL ;
14
+
15
+ newNode->isEOW = false ;
16
+ return newNode;
17
+ }
18
+ void insertNode (node *root, string key)
19
+ {
20
+ node *cur = root;
21
+ for (int i = 0 ; i < key.length (); i++)
22
+ {
23
+ int index = key[i] - ' a' ;
24
+ if (!cur->children [index ])
25
+ cur->children [index ] = createNode ();
26
+ cur = cur->children [index ];
27
+ }
28
+ cur->isEOW = true ;
29
+ }
30
+ bool searchKey (node *root, string key)
31
+ {
32
+ node *cur = root;
33
+ for (int i = 0 ; i < key.length (); i++)
34
+ {
35
+ int index = key[i] - ' a' ;
36
+ if (!cur->children [index ])
37
+ return false ;
38
+ cur = cur->children [index ];
39
+ }
40
+ return cur && cur->isEOW ;
41
+ }
42
+ bool dictionaryContains (vector<string> dictionary, string str)
43
+ {
44
+ for (int i = 0 ; i < dictionary.size (); i++)
45
+ {
46
+ if (dictionary[i].compare (str) == 0 )
47
+ return true ;
48
+ }
49
+ return false ;
50
+ }
51
+ bool wordBreakRecursive (vector<string> dictionary, string str)
52
+ {
53
+ int size = str.size ();
54
+
55
+ if (size == 0 )
56
+ return true ;
57
+ for (int i = 1 ; i <= size; i++)
58
+ {
59
+ if (dictionaryContains (dictionary, str.substr (0 , i)) && wordBreakRecursive (dictionary, str.substr (i, size - i)))
60
+ return true ;
61
+ }
62
+ return false ;
63
+ }
64
+ bool wordBreakDp4 (vector<string> dictionary, string str)
65
+ {
66
+ int size = str.size ();
67
+ vector<int > dp (size + 1 , 0 );
68
+ dp[0 ] = 1 ;
69
+ for (int i = 0 ; i < size; i++)
70
+ {
71
+ if (dp[i])
72
+ {
73
+ for (auto w : dictionary)
74
+ {
75
+ if (str.substr (i, w.size ()) == w)
76
+ dp[i + w.size ()] = 1 ;
77
+ }
78
+ }
79
+ }
80
+ return dp[size];
81
+ }
82
+ bool wordBreakDp2 (vector<string> dictionary, string str)
83
+ {
84
+ int size = str.size ();
85
+ vector<bool > dp (size + 1 , 0 );
86
+ vector<int > matchedIndex;
87
+ matchedIndex.push_back (-1 );
88
+ for (int i = 0 ; i < size; i++)
89
+ {
90
+ int f = 0 ;
91
+ int msize = matchedIndex.size ();
92
+ for (int j = msize - 1 ; j >= 0 ; j--)
93
+ {
94
+ string sub = str.substr (matchedIndex[j] + 1 , i - matchedIndex[j]);
95
+ if (dictionaryContains (dictionary, sub))
96
+ {
97
+ f = 1 ;
98
+ break ;
99
+ }
100
+ }
101
+ if (f)
102
+ {
103
+ dp[i] = 1 ;
104
+ matchedIndex.push_back (i);
105
+ }
106
+ }
107
+ return dp[size - 1 ];
108
+ }
109
+ bool wordBreakDp3 (node *root, string str)
110
+ {
111
+ int size = str.size ();
112
+ vector<bool > dp (size + 1 , 0 );
113
+ vector<int > matchedIndex;
114
+ matchedIndex.push_back (-1 );
115
+ for (int i = 0 ; i < size; i++)
116
+ {
117
+ int f = 0 ;
118
+ int msize = matchedIndex.size ();
119
+ for (int j = msize - 1 ; j >= 0 ; j--)
120
+ {
121
+ string sub = str.substr (matchedIndex[j] + 1 , i - matchedIndex[j]);
122
+ if (searchKey (root, sub))
123
+ {
124
+ f = 1 ;
125
+ break ;
126
+ }
127
+ }
128
+ if (f)
129
+ {
130
+ dp[i] = 1 ;
131
+ matchedIndex.push_back (i);
132
+ }
133
+ }
134
+ return dp[size - 1 ];
135
+ }
136
+ bool wordBreakDp (vector<string> dictionary, string str)
137
+ {
138
+ int size = str.size ();
139
+ int j;
140
+ if (size == 0 )
141
+ return true ;
142
+ vector<int > dp (size + 1 , 0 );
143
+ for (int i = 1 ; i <= size; i++)
144
+ {
145
+ if (!dp[i] && dictionaryContains (dictionary, str.substr (0 , i)))
146
+ dp[i] = 1 ;
147
+ if (dp[i])
148
+ {
149
+ if (i == size)
150
+ return true ;
151
+ for (j = i + 1 ; j <= size; j++)
152
+ {
153
+ if (!dp[j] && dictionaryContains (dictionary, str.substr (i, j - i)))
154
+ dp[j] = 1 ;
155
+ }
156
+ if (dp[i] && size == j)
157
+ return true ;
158
+ }
159
+ }
160
+ return false ;
161
+ }
162
+
163
+ int main ()
164
+ {
165
+ string str;
166
+ cout << " Enter string" << endl;
167
+ cin >> str;
168
+
169
+ vector<string> dictionary = {" mobile" , " samsung" , " sam" , " sung" , " man" , " mango" , " icecream" , " and" , " go" , " i" , " like" , " ice" , " cream" };
170
+ // 1
171
+ if (wordBreakRecursive (dictionary, str))
172
+ cout << " true" << endl;
173
+ else
174
+ cout << " false" << endl;
175
+
176
+ // 2
177
+ if (wordBreakDp (dictionary, str))
178
+ cout << " true" << endl;
179
+ else
180
+ cout << " false" << endl;
181
+
182
+ // 3
183
+ if (wordBreakDp2 (dictionary, str))
184
+ cout << " true" << endl;
185
+ else
186
+ cout << " false" << endl;
187
+
188
+ // 3
189
+ node *root = createNode ();
190
+ for (int i = 0 ; i < dictionary.size (); i++)
191
+ insertNode (root, dictionary[i]);
192
+ if (wordBreakDp3 (root, str))
193
+ cout << " true" << endl;
194
+ else
195
+ cout << " false" << endl;
196
+
197
+ // 4
198
+ if (wordBreakDp4 (dictionary, str))
199
+ cout << " true" << endl;
200
+ else
201
+ cout << " false" << endl;
202
+ return 0 ;
203
+ }
204
+ /*
205
+ - wordBreak: https://www.geeksforgeeks.org/word-break-problem-dp-32/
206
+ - methods
207
+ - recursive: Tc:(2^s \*n ), Sc:(n^2): recursive calls. s=length of string,n=length of dictionary
208
+ - Dp: Tc:O(s^2 \* n), Sc: o(s)
209
+ - Dp2: Tc:O(s\*n) Sc:O(s)
210
+ - Dp3: similar to Dp2, for checking whether the string present in dictionary use trie.
211
+ - Dp4: Tc: O(s\*n\*maxWordLengthOfDict)
212
+ */
0 commit comments