TheAlgorithms/C++ 1.0.0
All the algorithms implemented in C++
Loading...
Searching...
No Matches
word_break.cpp File Reference

Word Break Problem More...

#include <cassert>
#include <climits>
#include <iostream>
#include <string>
#include <unordered_set>
#include <vector>
Include dependency graph for word_break.cpp:

Go to the source code of this file.

Namespaces

namespace  dynamic_programming
 Dynamic Programming algorithms.
 
namespace  word_break
 Functions for Word Break problem.
 

Functions

bool dynamic_programming::word_break::exists (const std::string &str, const std::unordered_set< std::string > &strSet)
 Function that checks if the string passed in param is present in the the unordered_set passed.
 
bool dynamic_programming::word_break::check (const std::string &s, const std::unordered_set< std::string > &strSet, int pos, std::vector< int > *dp)
 Function that checks if the string passed in param can be segmented from position 'pos', and then correctly go on to segment the rest of the string correctly as well to reach a solution.
 
bool dynamic_programming::word_break::wordBreak (const std::string &s, const std::vector< std::string > &wordDict)
 Function that checks if the string passed in param can be segmented into the strings present in the vector. In others words, it checks if any permutation of strings in the vector can be concatenated to form the final string.
 
static void test ()
 Test implementations.
 
int main ()
 Main function.
 

Detailed Description

Word Break Problem

Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, determine if s can be segmented into a space-separated sequence of one or more dictionary words.

Note: The same word in the dictionary may be reused multiple times in the segmentation. You may assume the dictionary does not contain duplicate words.

Example 1: Input: s = "leetcode", wordDict = ["leet", "code"] Output: true Explanation: Return true because "leetcode" can be segmented as "leet code".

Example 2: Input: s = "applepenapple", wordDict = ["apple", "pen"] Output: true Explanation: Return true because "applepenapple" can be segmented as "apple pen apple". Note that you are allowed to reuse a dictionary word.

Example 3: Input: s = "catsandog", wordDict = ["cats", "dog", "sand", "and", "cat"] Output: false

Author
[Akshay Anand] (https://github.com/axayjha)

Definition in file word_break.cpp.

Function Documentation

◆ check()

bool dynamic_programming::word_break::check ( const std::string & s,
const std::unordered_set< std::string > & strSet,
int pos,
std::vector< int > * dp )

Function that checks if the string passed in param can be segmented from position 'pos', and then correctly go on to segment the rest of the string correctly as well to reach a solution.

Parameters
sthe complete string to be segmented
strSetunordered set of string, that is to be used as the reference dictionary
posthe index value at which we will segment string and test further if it is correctly segmented at pos
dpthe vector to memoize solution for each position
Returns
true if a valid solution/segmentation is possible by segmenting at index pos
false otherwise

Definition at line 80 of file word_break.cpp.

81 {
82 if (pos == s.length()) {
83 // if we have reached till the end of the string, means we have
84 // segmented throughout correctly hence we have a solution, thus
85 // returning true
86 return true;
87 }
88
89 if (dp->at(pos) != INT_MAX) {
90 // if dp[pos] is not INT_MAX, means we must have saved a solution
91 // for the position pos; then return if the solution at pos is true
92 // or not
93 return dp->at(pos) == 1;
94 }
95
96 std::string wordTillNow =
97 ""; // string to save the prefixes of word till different positons
98
99 for (int i = pos; i < s.length(); i++) {
100 // Loop starting from pos to end, to check valid set of
101 // segmentations if any
102 wordTillNow +=
103 std::string(1, s[i]); // storing the prefix till the position i
104
105 // if the prefix till current position is present in the dictionary
106 // and the remaining substring can also be segmented legally, then
107 // set solution at position pos in the memo, and return true
108 if (exists(wordTillNow, strSet) && check(s, strSet, i + 1, dp)) {
109 dp->at(pos) = 1;
110 return true;
111 }
112 }
113 // if function has still not returned, then there must be no legal
114 // segmentation possible after segmenting at pos
115 dp->at(pos) = 0; // so set solution at pos as false
116 return false; // and return no solution at position pos
117}
for std::vector
bool exists(const std::string &str, const std::unordered_set< std::string > &strSet)
Function that checks if the string passed in param is present in the the unordered_set passed.

◆ exists()

bool dynamic_programming::word_break::exists ( const std::string & str,
const std::unordered_set< std::string > & strSet )

Function that checks if the string passed in param is present in the the unordered_set passed.

Parameters
strthe string to be searched
strSetunordered set of string, that is to be looked into
Returns
true if str is present in strSet
false if str is not present in strSet

Definition at line 60 of file word_break.cpp.

61 {
62 return strSet.find(str) != strSet.end();
63}

◆ main()

int main ( void )

Main function.

Returns
0 on exit

Definition at line 174 of file word_break.cpp.

174 {
175 test(); // call the test function :)
176
177 // the complete string
178 const std::string s = "applepenapple";
179 // the dictionary to be used
180 const std::vector<std::string> wordDict = {"apple", "pen"};
181
182 // should return true, as applepenapple can be segmented as apple + pen +
183 // apple
184 std::cout << dynamic_programming::word_break::wordBreak(s, wordDict)
185 << std::endl;
186}
static void test()
Test implementations.
bool wordBreak(const std::string &s, const std::vector< std::string > &wordDict)
Function that checks if the string passed in param can be segmented into the strings present in the v...

◆ test()

static void test ( )
static

Test implementations.

Returns
void

Definition at line 156 of file word_break.cpp.

156 {
157 // the complete string
158 const std::string s = "applepenapple";
159 // the dictionary to be used
160 const std::vector<std::string> wordDict = {"apple", "pen"};
161
162 assert(dynamic_programming::word_break::wordBreak(s, wordDict));
163
164 // should return true, as applepenapple can be segmented as apple + pen +
165 // apple
166 std::cout << dynamic_programming::word_break::wordBreak(s, wordDict)
167 << std::endl;
168 std::cout << "Test implementation passed!\n";
169}

◆ wordBreak()

bool dynamic_programming::word_break::wordBreak ( const std::string & s,
const std::vector< std::string > & wordDict )

Function that checks if the string passed in param can be segmented into the strings present in the vector. In others words, it checks if any permutation of strings in the vector can be concatenated to form the final string.

Parameters
sthe complete string to be segmented
wordDicta vector of words to be used as dictionary to look into
Returns
true if s can be formed by a combination of strings present in wordDict
false otherwise

Definition at line 131 of file word_break.cpp.

131 {
132 // unordered set to store words in the dictionary for constant time
133 // search
134 std::unordered_set<std::string> strSet;
135 for (const auto &s : wordDict) {
136 strSet.insert(s);
137 }
138 // a vector to be used for memoization, whose value at index i will
139 // tell if the string s can be segmented (correctly) at position i.
140 // initializing it with INT_MAX (which will denote no solution)
141 std::vector<int> dp(s.length(), INT_MAX);
142
143 // calling check method with position = 0, to check from left
144 // from where can be start segmenting the complete string in correct
145 // manner
146 return check(s, strSet, 0, &dp);
147}