在Java中实现最佳匹配搜索

前端之家收集整理的这篇文章主要介绍了在Java中实现最佳匹配搜索前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在尝试使用现有 Java数据结构获得匹配匹配的最佳匹配字符串.这是相当缓慢的,但任何提高业绩的建议都将受到欢迎.

样本数据将如下所示

Key | V
--------------------- 
0060175559138 | VIP
--------------
006017555     | National
--------------
006017        | Local
---------------
0060          | X
--------------

所以最好的匹配搜索键= 0060175552020将返回006017555

我可以想到的一个方法是使用多个TreeMaps使用散列来将数据转移到不同的地图,从而使搜索区域更小.

private final TreeMap<String,V> index;

public Set<V> syncBestMatch(String key) {              
    Entry<String,V> entry = index.headMap(key,true)
                .descendingMap().entrySet().stream()
                .filter(e -> isPartiallyOrFullyMatching(key,e.getKey()))
                .findFirst()
                .orElseThrow(() -> new NoMatchException("No match found"));

    Set<V> results = new HashSet<>();
    results.add(entry.getValue());
    return results;
}

解决方法

使用TreeMap和 floorEntry(K key)方法

Returns a key-value mapping associated with the greatest key less than or equal to the given key,or null if there is no such key.

以下简化.如果找到无效条目,则实际代码将需要搜索.如果地图有一个键0060175551000,在这种情况下,您需要找到搜索键和找到的键之间的公用前缀,然后重新进行查找.冲洗并重复.

TreeMap<String,String> map = new TreeMap<>();
map.put("0060175559138","VIP");
map.put("006017555","National");
map.put("006017","Local");
map.put("0060","X");

String key = "0060175552020";
Entry<String,String> entry = map.floorEntry(key);
if (entry == null)
    System.out.println("Not found: " + key);
else {
    System.out.println(key);
    System.out.println(entry);
}

产量

0060175552020
006017555=National

更新有完整的代码,循环用于扩展搜索.

private static Entry<String,String> lookup(NavigableMap<String,String> map,String key) {
    String keyToFind = key;
    for (;;) {
        Entry<String,String> entry = map.floorEntry(keyToFind);
        if (entry == null)
            return null;
        String foundKey = entry.getKey();
        int prefixLen = 0;
        while (prefixLen < keyToFind.length() && prefixLen < foundKey.length() &&
               keyToFind.charAt(prefixLen) == foundKey.charAt(prefixLen))
            prefixLen++;
        if (prefixLen == 0)
            return null;
        if (prefixLen == foundKey.length())
            return entry;
        keyToFind = key.substring(0,prefixLen);
    }
}

测试

TreeMap<String,"VIP");
map.put("0060175551000","Other");
map.put("006017555","X");

System.out.println(lookup(map,"0060175559138"));
System.out.println(lookup(map,"0060175552020"));
System.out.println(lookup(map,"0055708570068"));
System.out.println(lookup(map,"8684064893870"));

产量

0060175559138=VIP
006017555=National
null
null

猜你在找的Java相关文章