Remember the word, LA 3942, Trie Tree

来源:互联网 发布:淘宝手机首页装修代码 编辑:程序博客网 时间:2024/05/16 07:35

给出一个由S个不同单词组成的字典和一个长字符串,把这个字符串分解成若干个单词的连接(单词可以重复使用),有多少种方法?比如4个单词 a、b、cd、ab 则 abcd 有两中分解方法:a+b+cd 和 ab + cd。

参考文献:《算法竞赛入门经典训练指南》P208,刘汝佳,陈锋

public class Trie {private final static int MAX_SIZE = 1024;private final static int SET_SIZE = 26;protected int[][]tree = null;protected int[]val = null;protected intsize = 0;public Trie() {tree = new int[MAX_SIZE][SET_SIZE];val = new int[MAX_SIZE];size = 1;initNode(0);}protected int index(char ch) {return ch - 'a';}// 初始化一个Tire树的结点,将其所有边置为无效状态0private void initNode(int i) {for ( int j=0; j< SET_SIZE; j++ ) {tree[i][j] = 0;}val[i] = 0;}// 向Trie树增加一个字符串public synchronized void insert(String s) {if ( s == null )throw new IllegalArgumentException();int cur = 0, i = 0;for ( i=0; i<s.length(); i++ ) {char ch = s.charAt(i);if ( tree[cur][index(ch)] == 0 ) {initNode(size);tree[cur][index(ch)] = size;size++;}cur = tree[cur][index(ch)];}val[cur]++;}// 查询字符串是否在Trie树public synchronized boolean query(String s) {if ( s == null )throw new IllegalArgumentException();int cur = 0, i = 0;for ( i=0; i<s.length(); i++ ) {char ch = s.charAt(i);if ( tree[cur][index(ch)] == 0 ) {return false;}cur = tree[cur][index(ch)];}return ( val[cur] > 0 );}// 打印Trie树public synchronized void print() {for ( int i=0; i<size; i++ ) {System.out.printf("%d[%d]: ", i, val[i]);for ( int j=0; j<SET_SIZE; j++ ) {if ( tree[i][j] > 0 )System.out.printf("%c-%d ", j+'a', tree[i][j]);}System.out.println();}}/** * @param args */public static void main(String[] args) {String[] strs = { "a", "to", "tea", "ted", "ten", "i", "in", "inn" };Trie inst = new Trie();for ( String s : strs ) inst.insert(s);inst.print();for ( String s : strs ) System.out.printf("%s - %b%n", s, inst.query(s));System.out.println(inst.query("abcdefg"));}}public class RememberTheWord_LA_3942 extends Trie {public int solve(String s) {int[] res = new int[s.length()+1];res[s.length()] = 1;for ( int i=s.length()-1; i>=0; i-- ) {int sum = 0;int k = i, cur = 0;while ( k < s.length() ) {char ch = s.charAt(k);if ( tree[cur][index(ch)] == 0 ) {// 从当前结点出发,沿s[k]字符边无效break;}// 从当前结点出发,沿s[k]字符边至下一结点cur = tree[cur][index(ch)];k++;// 在下一结点匹配上了一个单词if ( val[cur] > 0 ) {sum += res[k];}}res[i] = sum;}return res[0];}/** * @param args */public static void main(String[] args) {RememberTheWord_LA_3942 inst = new RememberTheWord_LA_3942();String[] strs = {"a","b","cd","ab"};for ( String s : strs ) inst.insert(s);int r = inst.solve("abcd");System.out.println(r);}}



原创粉丝点击