From e5a0475b4f8ad570c16168d7143d4906f9c69995 Mon Sep 17 00:00:00 2001 From: ashish Date: Mon, 6 Nov 2023 22:33:04 +0000 Subject: [PATCH] Added word break problem --- .../Dynamic-Programming/word-break.cpp | 115 ++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 algorithms/CPlusPlus/Dynamic-Programming/word-break.cpp diff --git a/algorithms/CPlusPlus/Dynamic-Programming/word-break.cpp b/algorithms/CPlusPlus/Dynamic-Programming/word-break.cpp new file mode 100644 index 00000000..37d10eaf --- /dev/null +++ b/algorithms/CPlusPlus/Dynamic-Programming/word-break.cpp @@ -0,0 +1,115 @@ +/* + +Given a string A and a dictionary of n words B. find out if A can be segmented into a +space-seprated sequence of dicrionary words. + + +Note: From the dictionary B each word can be taken any number of times +and in any order + +Example 1: + +N = 12 +B = {"i", "like", "sam", "sung", "samsung", "mobile", "ice", "icecream", "man", +"man", "go", "mango"} +A = "ilike" + +Ouput: 1 (True) +Explanation: +String can be segmented as "i like" + + +TOPICS: Dynamic Programing; Matrix Chain Multiplication Algo. + +*/ + + +#include +#include + +using namespace std; + +//Utility function to find if a string exist in dictionary (find in vector of string) +inline bool findVec(vector& vec, string str) +{ + return (find(vec.begin(), vec.end(), str) != vec.end()); +} + +// rec_fun with dictionary, indices of start and end of substring A and array to store previous rec. calls +int rec_fun(string A, vector& B, int start, int end, int** dp) +{ + + string partial_string = A.substr(start, end - start + 1); + if(dp[start][end] != -1) + return dp[start][end]; + if(findVec(B, partial_string)) // if substring found in the dictionary + { + dp[start][end] = 1; + return dp[start][end]; + } + if(start == end) // Base case with substring of size 1 and the substring not present in dictionary + { + dp[start][end] = 0; + return dp[start][end]; + } + + // Using Matrix Chain Multiplication fundamentals to partition string + // from k= start +1 to k = end + for(int k= start +1; k<=end; k++) + { + int l_subcall = rec_fun(A, B, start, k-1, dp); + if(!l_subcall) // if left partition substring's recursive call not found in dictionary try different value of k + continue; + int r_subcall = rec_fun(A, B, k, end, dp); + + if(l_subcall & r_subcall) // if both left and right subcalls are valid partitions then given string partition found in dictionary + { + dp[start][end] = 1; + return dp[start][end]; + } + + } + + dp[start][end] = 0; + return dp[start][end]; + +} + + +bool wordBreak(string A, vector& B ) +{ + //dp array used for memoizing the recursive calls + int end = A.size() -1; + int** dp = new int*[end+1]; + for(int i=0; i<=end; i++) + { + dp[i] = new int[end+1]; + for(int j=0; j<=end; j++) + dp[i][j] = -1; // initializing array with -1; + } + int start = 0; + return rec_fun(A, B, start, end, dp); +} + +int main() +{ + int t ; + cin>>t; + while(t--) + { + int n; + cin>>n; + + vector dict; + for(int i=0; i>s; + dict.push_back(s); + } + string line; + cin>>line; + cout<