I am trying to get a best match string matching to work using existing Java data structures. It is quite slow though, any suggestions to improve its performance will be welcomed
Use a TreeMap
and the floorEntry(K key) method:
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.
The following is simplified. Real code would need to search if an invalid entry is found, e.g. if the map had a key 0060175551000
, in which case you'd need to find the common prefix between the search key and the found key, then do the lookup again. Rinse and repeat.
TreeMap map = new TreeMap<>();
map.put("0060175559138", "VIP");
map.put("006017555" , "National");
map.put("006017" , "Local");
map.put("0060" , "X");
String key = "0060175552020";
Entry entry = map.floorEntry(key);
if (entry == null)
System.out.println("Not found: " + key);
else {
System.out.println(key);
System.out.println(entry);
}
Output
0060175552020
006017555=National
UPDATE There is the full code, with loop for extended search.
private static Entry lookup(NavigableMap map, String key) {
String keyToFind = key;
for (;;) {
Entry 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);
}
}
Test
TreeMap map = new TreeMap<>();
map.put("0060175559138", "VIP");
map.put("0060175551000", "Other");
map.put("006017555" , "National");
map.put("006017" , "Local");
map.put("0060" , "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"));
Output
0060175559138=VIP
006017555=National
null
null