设字符串为s,字符串中字符的个数为n,vi[i]表示前i+1个字符是否能组成有效的单词vi[i]=true表示能组成有效的单词,vi[i]=false表示不能组成有效的单词,在每个字符串前加一个空格,设vi[0]=true.只要有一个j满足vi[j]=true并且s[j+1,n-1]是一个有效的单词则整个字符串能重建为由合法单词组成的序列。
1 package org.xiu68.ch06.ex6; 2 3 import java.util.HashSet; 4 import java.util.Set; 5 6 //利用动态规划算法判断一个字符串是否由有效的单词组成,若是则输出单词序列,算法的运行时间不超过n的平方 7 public class Ex6_4 { 8 9 private static Set<String> wordSet; 10 11 public static void main(String[] args) { 12 // TODO Auto-generated method stub 13 wordSet=new HashSet<>(); 14 wordSet.add("it"); 15 wordSet.add("was"); 16 wordSet.add("the"); 17 wordSet.add("algorithoms"); 18 wordSet.add("best"); 19 wordSet.add("is"); 20 wordSet.add("of"); 21 wordSet.add("times"); 22 wordSet.add("interesting"); 23 wordSet.add("good"); 24 String strs1=" itwasthebestoftimesgood"; 25 checkWord(strs1); //true:it was the best of times good 26 27 String strs2=" algorithomsisinteresting"; 28 checkWord(strs2); //true:algorithoms is interesting 29 30 String strs3=" thisisastring"; 31 checkWord(strs3); //false: 32 } 33 34 public static void checkWord(String strs){ 35 boolean[] vi=new boolean[strs.length()]; //记录前i个字符组成的子串能否分割成有效的单词 36 vi[0]=true; 37 38 int[] index=new int[strs.length()]; //记录以该下标为终点的合法单词的起始位置 39 index[0]=-1; //不能构成合法单词 40 41 for(int i=1;i<=strs.length()-1;i++){ //判断前i+1个字符组成的子串能否分割成有效的单词 42 for(int j=i-1;j>=0;j--){ 43 String strTemp=strs.substring(j+1,i+1); 44 if(vi[j] && isAWord(strTemp)){ 45 vi[i]=true; 46 index[i]=j+1; 47 break; 48 } 49 else{ 50 vi[i]=false; 51 index[i]=-1; 52 } 53 } 54 55 }//外for 56 57 //打印出单词序列 58 System.out.print(vi[strs.length()-1]+":"); 59 if(vi[strs.length()-1]){ 60 String words=""; 61 int b=strs.length()-1; 62 int a=index[b]; 63 while(a!=-1){ 64 words=strs.substring(a,b+1)+" "+words; 65 b=a-1; 66 a=index[b]; 67 } 68 System.out.println(words); 69 } 70 71 } 72 73 //判断单词是否合法 74 public static boolean isAWord(String str){ 75 if(wordSet.contains(str)) 76 return true; 77 return false; 78 } 79 }