Given a string s and a dictionary of words dict, determine if s can be segmented into a space-separated sequence of one or more dictionary words.
For example, given
s = "leetcode"
,
dict = ["leet", "code"]
.
Return true because "leetcode"
can be segmented as "leet
code"
.
#include <string>
#include <unordered_set>
#include <iostream>
using namespace std;
class Node{
public:
bool end;
Node *node[26];
Node() : end(false)
{
for (int i = 0; i < 26; i++)
node[i] = NULL;
}
~Node()
{
for (int i = 0; i < 26; i++)
delete node[i];
}
void append(string s)
{
Node *iter = this;
int len = s.length();
for(int i = 0; i < len; i++)
{
if(iter->node[s[i] - 'a'] == NULL)
iter->node[s[i] - 'a'] = new Node();
iter = iter->node[s[i] - 'a'];
}
iter->end = true;
}
};
class Solution {
private:
int **f;
int n;
public:
Solution(): f(NULL){}
~Solution()
{
if(f != NULL)
{
for(int i = 0; i < n; i++)
delete []f[i];
delete []f;
}
}
//动态规划之备忘录做法
bool wordBreakI(string s, unordered_set<string> &dict)
{
n = s.length();
f = new int*[n];
for(int i = 0; i < n; i++)
f[i] = new int[n];
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
f[i][j] = 0;
return wordBreak(s, dict, 0, n);
}
bool wordBreak(string s, unordered_set<string> &dict, int start, int end)
{
if (f[start][end - 1] == -1)
return false;
if (f[start][end - 1] == 1)
return true;
string subs = s.substr(start, end - start);
if (dict.count(subs) != 0) //如果存在从start开始的长度为end - start的string
{
f[start][end - 1] = 1;
return true;
}
else
{
f[start][end - 1] = -1;
}
for (int j = start + 1; j < end; j++)
{
if(wordBreak(s, dict, start, j) && wordBreak(s, dict, j, end))
{
f[start][end - 1] = 1;
return true;
}
}
return false;
}
//动态规划之自底向上求法
bool wordBreakII(string s, unordered_set<string> &dict)
{
vector<bool> b(s.length() + 1, false);
b[0] = true;
int len = s.length() + 1;
//判断substr(0, i)能不能被分解
for (int i = 1; i < len; i++)
for (int j = i - 1; j >= 0; j--)
{
if (b[j] && dict.count(s.substr(j, i - j)) != 0)
b[i] = true;
}
return b[s.length()];
}
//字典树方法
bool wordBreak(string s, unordered_set<string> &dict)
{
Node node;
unordered_set<string>::iterator end = dict.end();
for (unordered_set<string>::iterator it = dict.begin(); it != end; it++)
node.append(*it);
int len = s.length();
vector<bool> b(s.length(), false);
findMatchWord(s, &node, 0, b);
for (int i = 0; i < len; i++)
{
if (b[i])
findMatchWord(s, &node, i + 1, b);
}
return b[s.length() - 1];
}
void findMatchWord(string &s, Node *iter, int start, vector<bool> &b)
{
int i = start;
int len = s.length();
while (i < len)
{
if (iter->node[s[i] - 'a'] != NULL)
{
if (iter->node[s[i] - 'a']->end)
b[i] = true;
iter = iter->node[s[i] - 'a'];
}
else
{
break;
}
i++;
}
}
};
int main()
{
Solution s;
string ss("ab");
unordered_set<string> unset;
unset.insert(string("a"));
unset.insert(string("b"));
cout << s.wordBreak(ss, unset);
return 0;
}