我写了以下程序及其测试。当我在eclipse上运行它时,我得到一个NullPointerException。我不知道如何解决。
该计划的作用:
这是一个包含两种方法的数据结构:addWord(word)
和search(word)
。 search(word)
可以搜索只包含字母a-z
或.
的文字或正则表达式字符串。 .
表示它可以代表任何一个字母。
例如:
addWord("bad")
addWord("dad")
addWord("mad")
search("pad") -> false
search("bad") -> true
search(".ad") -> true
search("b..") -> true
在我向您展示我的代码之前,让我展示测试用例并指出导致NPE发生的原因。
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
public class WordDictionaryText {
@Test
public void test() {
WordDictionary dict = new WordDictionary();
List<Boolean> result = new ArrayList<>();
dict.addWord("ran");
dict.addWord("rune");
dict.addWord("runner");
dict.addWord("runs");
dict.addWord("add");
dict.addWord("adds");
dict.addWord("adder");
dict.addWord("addee");
result.add(dict.search("r.n"));
result.add(dict.search("ru.n.e"));
result.add(dict.search("add"));
result.add(dict.search("add."));
result.add(dict.search("adde."));
result.add(dict.search(".an.”));//NPE caused by this line: i.e. by searching for string “.an.”
result.add(dict.search("...s"));
result.add(dict.search("....e."));
result.add(dict.search("......."));
result.add(dict.search("..n.r"));
System.out.println(result);
}
}
因此,NPE是由行dict.search(".an.”)
引起的。
这是完整的代码。
import java.util.HashMap;
import java.util.Map;
public class WordDictionary {
Trie trie;
public WordDictionary() {
trie = new Trie();
}
// Adds a word into the data structure.
public void addWord(String word) {
trie.addWord(word);
}
// Returns if the word is in the data structure. A word could
// contain the dot character '.' to represent any one letter.
public boolean search(String word) {
if (null != word && !word.isEmpty()) {
return trie.findWord(word);
}
return false;
}
}
// /////////////////////////////
class Trie {
TrieNode root;
public Trie() {
root = new TrieNode((char) 0);
}
public void addWord(String word) {
TrieNode node = root;
for (char c : word.toCharArray()) {
TrieNode next = node.getNext(c);
if (null == next) {
next = new TrieNode(c);
node.addNext(c, next);
}
node = next;
}
node.isWord = true;
}
boolean findWord(String word) {
TrieNode nextNode = root;
for (int i = 0; i < word.length(); i++) {
char curr = word.charAt(i);
if ('.' != curr) {
nextNode = nextNode.getNext(curr);
if (null == nextNode) {
return false;
}
} else {
java.util.Collection<TrieNode> collection = nextNode.getNextList();
if (!collection.isEmpty()) {
for (TrieNode tmp : nextNode.getNextList()) {
if (findWord(word, tmp)) {
return true;
}
}
}
return false;
}
}
return nextNode.isWord;
}
boolean findWord(String word, TrieNode nextNode) {
for (int i = 0; i < word.length(); i++) {
char curr = word.charAt(i);
if ('.' == curr) {
java.util.Collection<TrieNode> collection = nextNode.getNextList();
if (i + 1 < word.length() && !collection.isEmpty()) {
for (TrieNode tmp : collection) {
if (null != tmp && findWord(word.substring(i + 1), tmp)) {
return true;
}
}
return false;
} else {
return nextNode.isWord;
}
} else if (curr != nextNode.val) {
return false;
}
if (i + 1 < word.length()) {
nextNode = nextNode.getNext(word.charAt(i + 1));
}
}
return nextNode.isWord;
}
}
// /////////////////////////////
class TrieNode {
char val;
Map<Character, TrieNode> next;
boolean isWord;
public TrieNode(char val) {
this.val = val;
next = new HashMap<>();
}
public TrieNode getNext(char c) {
return next.get(c);
}
public void addNext(char c, TrieNode node) {
next.put(c, node);
}
public java.util.Collection<TrieNode> getNextList() {
return next.values();
}
}
随意复制并粘贴到eclipse中的代码和测试。谢谢你的帮助。
如果您无法在Eclipse上运行该程序,则出现错误
java.lang.NullPointerException
at algo.Trie.findWord(WordDictionary.java:80)
at algo.Trie.findWord(WordDictionary.java:83)
at algo.Trie.findWord(WordDictionary.java:64)
at algo.WordDictionary.search(WordDictionary.java:23)
at test.WordDictionaryText.test(WordDictionaryText.java:29)
错误对应
line 80: java.util.Collection<TrieNode> collection = nextNode.getNextList();
line 83: if (null != tmp && findWord(word.substring(i + 1), tmp))
line 64: if (findWord(word, tmp))
line 23: return trie.findWord(word);
更新:问题被错误地拒绝回答,但我有答案: findWord()具有nextNode值的递归和迭代推进。迭代推进是将值设置为null。
在行上的findWord()中放置一个断点: nextNode = nextNode.getNext(word.charAt(i + 1));