DP32 单词按照字典分割问题 Word Break Problem @geeksforgeeks
2013-12-30 01:11
267 查看
Given an input string and a dictionary of words, find out if the input string can be segmented into a space-separated sequence of dictionary words. See following examples for more details.
This is a famous Google interview question, also being asked by many other companies now a days.
Recursive implementation:
The idea is simple, we consider each prefix and search it in dictionary. If the prefix is present in dictionary, we recur for rest of the string (or suffix). If the recursive call for suffix returns true, we return true, otherwise we try next prefix. If we
have tried all prefixes and none of them resulted in a solution, we return false.
经典DFS题目,把DFS改成DP能减少运算量
package DP;
import java.util.ArrayList;
public class WordBreak {
public static void main(String[] args) {
System.out.println(wordBreakRec("ilikesamsung"));
System.out.println(wordBreakDP("ilikesamsung"));
wordBreakPrintAll("ilikesamsung");
System.out.println(wordBreakRec("samsungandmango"));
System.out.println(wordBreakDP("samsungandmango"));
wordBreakPrintAll("samsungandmango");
System.out.println(wordBreakRec("samsungandmangok"));
System.out.println(wordBreakDP("samsungandmangok"));
wordBreakPrintAll("samsungandmangok");
}
public static boolean wordBreakRec(String s){
int len = s.length();
if(len == 0){
return true;
}
// DFS
// Try all prefixes of lengths from 1 to size
for(int i=1; i<=len; i++){
// The parameter for dictionaryContains is s.substring(0, i)
// s.substring(0, i) which is prefix (of input string) of
// length 'i'. We first check whether current prefix is in
// dictionary. Then we recursively check for remaining string
// s.substring(i) which is suffix of length size-i
if(dictionaryContains(s.substring(0, i)) && wordBreakRec(s.substring(i))){
return true;
}
}
// If we have tried all prefixes and none of them worked
return false;
}
// 打印出所有组合,因为要打印出所有组合而不只是判断能否,所以只能用dfs
public static void wordBreakPrintAll(String s){
ArrayList<String> al = new ArrayList<String>();
wordBreakRec2(s, al);
}
public static void wordBreakRec2(String s, ArrayList<String> al){
int len = s.length();
if(len == 0){
System.out.println(al);
return;
}
// DFS
for(int i=1; i<=len; i++){
String substr = s.substring(0, i);
if(dictionaryContains(substr)){
al.add(substr);
wordBreakRec2(s.substring(i), al);
al.remove(al.size()-1);
}
}
}
private static boolean dictionaryContains(String word){
String[] dict = {"mobile","samsung","sam","sung","man","mango",
"icecream","and","go","i","like","ice","cream"};
for(int i=0; i<dict.length; i++){
if(dict[i].equals(word)){
return true;
}
}
return false;
}
// Returns true if string can be segmented into space separated
// words, otherwise returns false
public static boolean wordBreakDP(String s){
int len = s.length();
if(len == 0){
return true;
}
// Create the DP table to store results of subproblems. The value wb[i]
// will be true if s[0..i-1] can be segmented into dictionary words,
// otherwise false.
boolean[] wb = new boolean[len+1];
for(int i=1; i<=len; i++){
// if wb[i] is false, then check if current prefix can make it true.
// Current prefix is "s.substring(0, i)"
if(wb[i]==false && dictionaryContains(s.substring(0, i))){
wb[i] = true;
}
// wb[i] is true, then check for all substrings starting from
// (i+1)th character and store their results.
if(wb[i] == true){
if(i == len){ // If we reached the last prefix
return true;
}
for(int j=i+1; j<=len; j++){
// Update wb[j] if it is false and can be updated
// Note the parameter passed to dictionaryContains() is
// substring starting from index 'i' to index 'j-1'
if(wb[j]==false && dictionaryContains(s.substring(i, j))){
wb[j] = true;
}
if(j==len && wb[j]==true){ // If we reached the last character
return true;
}
}
}
}
// for(int i=1; i<=len; i++){
// System.out.print(wb[i] + " ");
// }
// If we have tried all prefixes and none of them worked
return false;
}
}
http://www.geeksforgeeks.org/dynamic-programming-set-32-word-break-problem/
This is a famous Google interview question, also being asked by many other companies now a days.
Consider the following dictionary { i, like, sam, sung, samsung, mobile, ice, cream, icecream, man, go, mango} Input: ilike Output: Yes The string can be segmented as "i like". Input: ilikesamsung Output: Yes The string can be segmented as "i like samsung" or "i like sam sung".
Recursive implementation:
The idea is simple, we consider each prefix and search it in dictionary. If the prefix is present in dictionary, we recur for rest of the string (or suffix). If the recursive call for suffix returns true, we return true, otherwise we try next prefix. If we
have tried all prefixes and none of them resulted in a solution, we return false.
经典DFS题目,把DFS改成DP能减少运算量
package DP;
import java.util.ArrayList;
public class WordBreak {
public static void main(String[] args) {
System.out.println(wordBreakRec("ilikesamsung"));
System.out.println(wordBreakDP("ilikesamsung"));
wordBreakPrintAll("ilikesamsung");
System.out.println(wordBreakRec("samsungandmango"));
System.out.println(wordBreakDP("samsungandmango"));
wordBreakPrintAll("samsungandmango");
System.out.println(wordBreakRec("samsungandmangok"));
System.out.println(wordBreakDP("samsungandmangok"));
wordBreakPrintAll("samsungandmangok");
}
public static boolean wordBreakRec(String s){
int len = s.length();
if(len == 0){
return true;
}
// DFS
// Try all prefixes of lengths from 1 to size
for(int i=1; i<=len; i++){
// The parameter for dictionaryContains is s.substring(0, i)
// s.substring(0, i) which is prefix (of input string) of
// length 'i'. We first check whether current prefix is in
// dictionary. Then we recursively check for remaining string
// s.substring(i) which is suffix of length size-i
if(dictionaryContains(s.substring(0, i)) && wordBreakRec(s.substring(i))){
return true;
}
}
// If we have tried all prefixes and none of them worked
return false;
}
// 打印出所有组合,因为要打印出所有组合而不只是判断能否,所以只能用dfs
public static void wordBreakPrintAll(String s){
ArrayList<String> al = new ArrayList<String>();
wordBreakRec2(s, al);
}
public static void wordBreakRec2(String s, ArrayList<String> al){
int len = s.length();
if(len == 0){
System.out.println(al);
return;
}
// DFS
for(int i=1; i<=len; i++){
String substr = s.substring(0, i);
if(dictionaryContains(substr)){
al.add(substr);
wordBreakRec2(s.substring(i), al);
al.remove(al.size()-1);
}
}
}
private static boolean dictionaryContains(String word){
String[] dict = {"mobile","samsung","sam","sung","man","mango",
"icecream","and","go","i","like","ice","cream"};
for(int i=0; i<dict.length; i++){
if(dict[i].equals(word)){
return true;
}
}
return false;
}
// Returns true if string can be segmented into space separated
// words, otherwise returns false
public static boolean wordBreakDP(String s){
int len = s.length();
if(len == 0){
return true;
}
// Create the DP table to store results of subproblems. The value wb[i]
// will be true if s[0..i-1] can be segmented into dictionary words,
// otherwise false.
boolean[] wb = new boolean[len+1];
for(int i=1; i<=len; i++){
// if wb[i] is false, then check if current prefix can make it true.
// Current prefix is "s.substring(0, i)"
if(wb[i]==false && dictionaryContains(s.substring(0, i))){
wb[i] = true;
}
// wb[i] is true, then check for all substrings starting from
// (i+1)th character and store their results.
if(wb[i] == true){
if(i == len){ // If we reached the last prefix
return true;
}
for(int j=i+1; j<=len; j++){
// Update wb[j] if it is false and can be updated
// Note the parameter passed to dictionaryContains() is
// substring starting from index 'i' to index 'j-1'
if(wb[j]==false && dictionaryContains(s.substring(i, j))){
wb[j] = true;
}
if(j==len && wb[j]==true){ // If we reached the last character
return true;
}
}
}
}
// for(int i=1; i<=len; i++){
// System.out.print(wb[i] + " ");
// }
// If we have tried all prefixes and none of them worked
return false;
}
}
http://www.geeksforgeeks.org/dynamic-programming-set-32-word-break-problem/
相关文章推荐
- Python: The Dictionary Playbook
- Linux系统管理员需要知道的16个服务器监控命令
- Python: Common Newbie Mistakes, Part 2
- 使用java NIO实现复制文件
- Python: Common Newbie Mistakes, Part 1
- hadoop-入门
- Android游戏开发十日通(7)- 开发一个双人游戏
- Android游戏开发十日通(7)- 开发一个双人游戏
- 半个程序猿
- 直接插入排序
- 使用Python进行稳定可靠的文件操作
- php main 与 iframe 相互通讯类(同域/跨域)
- php main 与 iframe 相互通讯类(同域/跨域)
- 浅析人脸检测之Haar分类器方法
- python:常用功能之文本处理
- Android学习第二天——Intent & Activity的生命周期
- Mysql UPDATE
- Android之提交multipart/form-data类型数据
- c# 异常找不到源代码的情况
- [cocos2dx]随机数的使用