考虑到不同公司的分机号码位数不同,不同国家和地区的电话号码位数也可能不同,这是一个需要高效解决的棘手问题。即使你将数据表拆分为基础号码和分机号码,你仍然需要将来电号码拆分为基础号码和分机号码,我认为这实际上会让事情变得更加复杂。
我倾向于尝试以下方法:
原始格式
1. 尝试将来电号码与数据库匹配。
- 如果它匹配一个记录,那么你就可以得到答案 - 特定人员。
- 如果它匹配多个记录,那么出了问题,所以失败。
- 否则,你必须找到公司:
2. 去掉来电号码末尾的一位数字,再次尝试将其与数据库匹配。
- 如果数字位数低于阈值(可能是6位数字),那么你的搜索应该失败。这只是为了在不会找到号码时限制执行的数据库搜索数量。
- 如果它没有匹配任何记录,则需要再次尝试此步骤。
- 如果它匹配多个记录,那么出了问题,所以失败。
- 如果它恰好匹配一个记录,那么就可以得到下一个最佳答案 - 公司。
例如,在查找“+43123456777”时:
- +43123456777不匹配任何记录。
- +4312345677不匹配任何记录。
- +431234567匹配1个记录:“公司A”
这种方法的主要故障模式是如果公司的分机号码长度可变。例如,考虑如果431234567890和43123456789都是有效的电话号码,但只有第二个号码在数据库中。如果来电号码是431234567890,则会误匹配43123456789。
拆分格式
这更加复杂,但更健壮。
尝试将传入号码与数据库匹配:
- 如果它与一条记录匹配,则您有答案-公司。
- 如果它与多个记录匹配,请匹配没有分机的条目,然后您就找到了公司。
- 否则,您必须找到基础公司号码和分机号码:
从传入号码中去掉末尾数字,然后再次尝试将其与数据库匹配。
- 如果数字数量低于阈值(可能是6位数字),则您的搜索可能会失败。这只是为了在不会找到号码时限制执行的数据库搜索次数。
- 如果没有匹配记录,则需要再次尝试此步骤。
- 如果它与一条记录匹配,则您已经找到了答案-公司。
- 如果它与多个记录匹配,则您已经找到了公司的基础号码,因此现在知道了分机号码,因此可以尝试查找特定人员:
从原始传入号码的开头剥离基础号码,并使用此号码搜索具有该基础号码的记录的扩展名。
- 如果它与一条记录完全匹配,则您已经找到了一个特定的人员。
- 如果它没有匹配特定的人员,则匹配没有分机的条目,然后您就找到了公司。
例如,在搜索“+ 43123456777”时:
- +43123456777与0个条目匹配。
- +4312345677与0个条目匹配。
- +431234567与2个条目匹配:“empty:Company A”和“890:employee in company A”。
- 在这两个匹配项中,“77”没有匹配项,因此返回空扩展名:“Company A”。
实现注意事项:
如上所述,此算法确实存在一些效率问题。如果数据库查找很昂贵,则它具有与电话号码长度相关的线性成本,特别是在数据库中不存在类似的号码的情况下(例如,如果传入号码来自哈萨克斯坦,但数据库中没有哈萨克斯坦号码)* 8')。
不过,您可以相对容易地添加一些优化。如果您处理的大多数公司使用3或4位数字分机,您可以从末尾剥离4位数字,然后进行二分查找,直到达到答案。这将在许多情况下将15位数字减少到4或5位,并最多进行6次查找。
此外,每次缩小选择范围时,您都可以仅在先前选择范围内进行选择,而无需在整个数据库中进行选择。
终于弄清楚了Unreason的答案如何工作,我发现这是一个更简单、更优雅的解决方案。我希望我能想到在传入号码中查找数据库号码而不是反过来。
我的唯一担忧是,在数据库中对每个telephonenumber
执行此操作可能会对服务器造成过多的负担。我建议在最大压力下对该解决方案进行基准测试,看它是否会引起问题。如果没有问题,那就好 - 使用它。如果有问题,考虑实施我的算法的简单形式,并再次进行压力测试。如果性能仍然太低,可以尝试使用我的二分搜索建议。