我实现了一种算法来进行目录匹配。所以我给出了一组可以包含通配符的有效路径(用&#34表示; X")。然后当我传入一个输入时,我需要知道该输入是否与我的有效集中的一个路径匹配。当传入的通配符值实际上与另一个有效值匹配时,我遇到了通配符问题。这是一个例子:
有效路径集:
/guest
/guest/X
/X/guest
/member
/member/friends
/member/X
/member/X/friends
示例输入:
/member/garbage/friends
/member/friends/friends
这些都应该返回true,但只有第一个返回true。在第一种情况下因为"垃圾"与另一个其他可能的路径不匹配,但此时有一个通配符选项,它会跳过它并继续前进,然后它会看到" friends"而且它知道这是一场比赛。但是,我的第二种情况不起作用,因为它看到了朋友,并在我的特里,而不是通配符路径中的不同路径。因为"朋友"有一个有效的路径。在这个位置,它认为会是这样。然后它会看到"朋友"再次,但从这一点来看,没有有效的路径与朋友"所以它返回false。
我的问题是,即使它在trie中的错误分支出现,我怎样才能识别出其他有效路径。我的搜索代码和示例trie图如下所示。
我的trie的搜索算法如下:
private TrieNode searchNode(String input) {
Map<String, TrieNode> children = root.children;
TrieNode t = null;
// break up input into individual tokens
String[] tokenizedLine = input.split("/");
for(int i = 0; i < tokenizedLine.length; i++){
String current = tokenizedLine[i];
if(children.containsKey(current)) {
t = children.get(current);
children = t.children;
}else if(children.containsKey("X")){
t = children.get("X");
children = t.children;
}else{
return null;
}
}
return t;
}
将使用我的样本路径集构建的trie图像: 当我输入/ member / friends / friends时,我的算法会沿着突出显示的路径向下停止,因为它没有看到另一个&#34;朋友&#34;之后,但我怎样才能让它认出第一个朋友&#34;作为通配符值,所以它会继续,并看到第二个&#34;朋友&#34;在通配符之后?
感谢您的帮助!
答案 0 :(得分:3)
想出来。我实现了一些回溯来跟踪它看到两条可能路径的最后一个节点。如果它在一条路径上找到一个死胡同,它将返回到它最后一次看到两条可能的路径并尝试另一条路径。新算法如下所示:
private TrieNode searchNode(String input) {
Map<String, TrieNode> children = root.children;
TrieNode t = null;
// Variables for backtrack function
TrieNode alternativeWildcardNode = null;
int wildcardIndex = 0;
Map<String, TrieNode> wildcardChildren = root.children;
// break up input into individual tokens
String[] tokenizedLine = input.split("/");
for(int i = 0; i < tokenizedLine.length; i++){
String current = tokenizedLine[i];
//System.out.println(current);
//System.out.println(Integer.toString(i));
if(children.containsKey(current) && children.containsKey("X")) {
// store current variable state in case we need to back track here
alternativeWildcardNode = children.get("X");
wildcardIndex = i;
wildcardChildren = alternativeWildcardNode.children;
t = children.get(current);
children = t.children;
}else if(children.containsKey(current)) {
t = children.get(current);
children = t.children;
}else if(children.containsKey("X")){
t = children.get("X");
children = t.children;
}else if(alternativeWildcardNode != null){
// if we've reached a branch with no match, but had a possible wildcard previously
// call reset state to the wildcard option instead of static
t = alternativeWildcardNode;
alternativeWildcardNode = null;
i = wildcardIndex;
children = wildcardChildren;
}else{
return null;
}
}
return t;
}