我可以想象我需要从长度为 1 的单词开始,并建立长度增加的子字符串,但我无法得出可以有效存储子问题结果的数据结构
以下是用Java编写的伪代码可能无法编译
TrieNode.java
class TrieNode
{
public TrieNode (double a, double b, double g, int size)
{
this.alpha = a;
this.beta = b;
this.gamma = g;
this.next = new TrieNode [size];
}
public double alpha, beta, gamma;
public TrieNode [] next;
}
您可以将alpha、beta、gamma 替换为问题的参数。
Trie.java
class Trie
{
private TrieNode root;
private char base;
private final int ALPHABET_SIZE;
public Trie (int ALPHABET_SIZE, char base_char)
{
this.base = base_char;
this.root=new TrieNode(0,0,0,ALPHABET_SIZE);
}
public boolean insert (String word, double [] param)
{
TrieNode current = this.root;
int i = (-1);
if (!validate(word))
return false;
char [] c = word.toCharArray();
for (int i = 0; i < (c.length-1); i++)
{
if (current.next[c[i]-base] == null)
current.next[c[i]-base] = new TrieNode (0,0,0,ALPHABET_SIZE);
current = current.next[c[i]-base];
}
if (current.next[c[i]-base] == null)
current.next[c[i]-base] = new TrieNode (0,0,0,ALPHABET_SIZE);
current.next[c[i]-base].alpha = param[0];
current.next[c[i]-base].beta = param[1];
current.next[c[i]-base].gamma = param[2];
return true;
}
public boolean validate (String word)
{
for (char c : word.toCharArray())
if (c < base || c > (base+ALPHABET_SIZE-1))
return false;
}
}
这是一个基于索引的Trie,具有安全插入功能。
MappedTrie.java
class MappedTrie
{
public final char [] ALPHABET;
private Trie trie;
MappedTrie (char [] alphabet)
{
ALPHABET = alphabet;
trie = new Trie (ALPHABET.length,0);
}
public boolean insert (String word, double [] param)
{
if (!validate(word))
return false;
String key = "";
for (char c : word.toCharArray())
key += encode(c);
return trie.insert(key,param);
}
private char encode (char c)
{
for (int i=0; i<ALPHABET.length; i++)
if (c == ALPHABET[i])
return i;
}
private char decode (char d)
{
return ALPHABET[d];
}
public boolean validate (String word)
{
boolean exist = false;
for (char c : word.toCharArray())
{
exist = false;
for (char d : ALPHABET) if (c == d) { exist = true; break; }
if (!exist) return false;
}
return true;
}
}
如果自定义字母表中的字符不相邻,我们可以将其映射到索引上。
测试
class Test
{
public static void main (String [] args)
{
// 'a'+0, 'a'+1, 'a'+2
MappedTrie k = new MappedTrie(3, 'a');
k.insert("aa", { 0.1, 0.2, 0.3 });
k.insert("ab", { 0.4, 0.5, 0.6 });
k.insert("ac", { 0.7, 0.8, 0.9 });
k.insert("ba", { 0.01, 0.02, 0.03 });
k.insert("bb", { 0.04, 0.05, 0.06 });
k.insert("bc", { 0.07, 0.08, 0.09 });
k.insert("ca", { 0.001, 0.002, 0.003 });
k.insert("cb", { 0.004, 0.005, 0.006 });
k.insert("cc", { 0.007, 0.008, 0.009 });
// 'a' => 0, 'b' => 1, 'c' => 2
MappedTrie t = new MappedTrie({'a','b','c'});
t.insert("aa", { 0.1, 0.2, 0.3 });
t.insert("ab", { 0.4, 0.5, 0.6 });
t.insert("ac", { 0.7, 0.8, 0.9 });
t.insert("ba", { 0.01, 0.02, 0.03 });
t.insert("bb", { 0.04, 0.05, 0.06 });
t.insert("bc", { 0.07, 0.08, 0.09 });
t.insert("ca", { 0.001, 0.002, 0.003 });
t.insert("cb", { 0.004, 0.005, 0.006 });
t.insert("cc", { 0.007, 0.008, 0.009 });
}
}