使用通配符值实现实现

时间:2017-07-24 01:12:24

标签: algorithm validation pattern-matching binary-search-tree trie

我实现了一种算法来进行目录匹配。所以我给出了一组可以包含通配符的有效路径(用&#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图像: enter image description here 当我输入/ member / friends / friends时,我的算法会沿着突出显示的路径向下停止,因为它没有看到另一个&#34;朋友&#34;之后,但我怎样才能让它认出第一个朋友&#34;作为通配符值,所以它会继续,并看到第二个&#34;朋友&#34;在通配符之后?

感谢您的帮助!

1 个答案:

答案 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;
    }