获得更好的索引
通过直接订购前缀,而不是长度(前缀):
SELECT dialstring FROM call_routing
WHERE number like prefix || '%'
ORDER BY prefix DESC
LIMIT 1
为什么?
因为数字的选定行将abcdef
是前缀。所以将是这样的数字:
ab abc abcd
因此,如果您按字母顺序对它们进行排序,就足以得到一个从最长到最短的列表,这就是您想要的。
您还可以使用以下方法获得更强大的过滤器:
prefix between 'a' and 'abcde'
. 您所有的前缀将是按字母顺序排列>=
的最短前缀和按字母顺序排列<=
的最长前缀。
所以可以表示为:
SELECT dialstring FROM call_routing WHERE
prefix between substr(number, 1, 1) and number -- range filter (use index)
AND number like prefix || '%' -- only relevant data (normal filter)
ORDER BY prefix DESC -- index will work
LIMIT 1
当然,索引将位于列前缀上。
全部缓存?
是的,请。:)
你有多少物品?如果它不是一个巨大的列表,请将其加载到内存中。
然后你可以有一个 TreeMap (如果你想按前缀排序)或一个 HashMap (如果你喜欢先找到最长的前缀,然后每次尝试少一个字符)。哪一个会更好?取决于范围内a >> abcde
且不匹配like
条件的前缀数量(abbde
通过示例)。
如果没有很多条目
您可以使用按前缀 desc 排序的数组:
be
b
abcde
abbbc
abd
ab
要找到合适的前缀,请检查Arrays.binarySearch(T[], T key, Comparator<T>)
您的手机是否在其中 ( abcde
)。如果是……好的。如果不是你继续前进,直到:
- you find a prefix (OK, this is the winner)
- it doesn't start with the same char (there are no prefix)
这样你就可以遍历范围abcde >> a
并找到第一个前缀(它是最长的)。
好的一个
正在制作一棵树(我不确定名称)。制作一棵树,其中每个节点仅包含一个字母(在您的情况下为数字)。
0 // represents 0
->
2 // represents 02
-> 1 // represents 021
-> 3 // represents 023
->
4 // represents 04
因此,当您寻找最长的前缀时,您会尝试在树中尽可能深入:
Node n = root;
for (char c: number) {
if ((child = n.hasChild(c)) != null)
{
prefix += c;
n = child;
}
else
break;
}
你只需要一个来创建一个
class Node
{
int digit;
Map<Integer, Node> childs = new HashMap<Integer, Node>(); // or a 10 bucket array :)
YourInfo info;
}
并用于创建结构:
findOrCreateNode(prefix).setInfo(info);
其中 findOrCreateNode 与以前相同,但是当它没有找到节点时......创建它(n.put(c, new Node(c))
)。