1
2
假设每个公司的分机号码可以不同 和 数字中的位数可能因国家和地区代码而异,这是一个需要有效解决的棘手问题。 即使将数据表拆分为基数和扩展名,也必须将传入的数字拆分为基数和扩展名,我认为这会使事情复杂化。 我想尝试的是: 原始格式
例如,搜索“+43123456777”:
这种方法的主要失败模式是如果一个公司有可变长度的扩展号。例如,如果431234567890和43123456789都是有效数字,但只有第二个数字在数据库中,会发生什么情况。如果输入的号码是431234567890,则43123456789将错误匹配。 拆分格式这有点复杂,但更健壮。
例如,搜索“+43123456777”:
实施说明如上所述,该算法确实存在一些效率问题。如果数据库查找成本很高,则它具有与电话号码长度相关的线性成本,特别是在数据库中不存在类似号码的情况下(例如,如果传入号码来自哈萨克斯坦,但数据库*8中没有哈萨克斯坦号码)。 不过,您可以相对容易地添加一些优化。如果与你打交道的大多数公司都使用3或4位扩展名,你可以先从末尾去掉4位数字,然后进行二进制切分,直到你找到答案。在许多情况下,这会将15位数减少到4或5,最多可以查找6次。 此外,每次缩小选择范围时,都只能在上一个选择范围内进行选择,而不必在整个数据库中进行选择。 附加实施说明终于弄明白了 Unreason's answer 好的,我可以看到这是一个更简单,更优雅的解决方案。我希望我能简单地在输入的号码中查找数据库号码,而不是相反。
我唯一关心的是
|
2
4
有没有办法确定存储号码的哪一部分是分机? 或者是没有扩展的“基数”被存储。 如果是,您可以检查数据库中的数字(不带扩展名)是否是要检查的当前数字的前缀。 前缀是指从开头开始的字符串的子字符串。 但是如果你的数据库中只有带扩展名的数字,而且没有办法找出有多少个数字属于它,我相信你找不到确切的答案。 |
3
2
不必在数据库中查找电话号码,您可以反转问题并检查数据库中的每个号码,看是否匹配 或前缀 输入的号码。 假设你从来电显示中得到一个电话号码,比如+431234567891,那么
将返回公司,在+431234567890的情况下将返回2个记录
如果您可以处理从客户端返回的两行,那么您应该可以处理上面的问题。 预处理数据更好(性能方面),但为此您需要更详细地描述数据,例如:
|
4
1
分机中的位数是特定于PBX的。 区号+电话号码中的数字位数取决于国家/运营商。 一种方法是定义额外的规则,例如… +43123 12 …要说以+43123开头的任何内容都是一个12位数的数字,超出这个数字的任何内容都是一个扩展:这允许您使用(可配置的而不是硬编码的)数据来指定扩展的开始位置。 另一种方法可能是坚持对于任何带有扩展项的数字,也应该有一个没有扩展项的对应数字,如您的“公司A”示例所示。 |
5
1
好吧,我对电话号码系统的理解是,如果一个号码是另一个号码的前缀,那么就不可能存在两个有效/完整的号码。这里一个常见的恶作剧是把你的电话号码打成110532或其他什么,其中110是德国紧急警察的号码。 因此-如果您可以更改数据库结构并对数据进行预处理,那么您可以查找具有相同前缀的数字(如果较长的数字以最短的为扩展名,请先排序)。每一场比赛
如果可能的话,我会在数据库中标记这些以便更快地查找。 这种方法不适用于具有通用默认扩展名的情况。在这里,很多公司都会将1234567-0作为外部号码,其中0可以替换为2-4位的扩展名。在这些情况下,我的方法可能会有缺陷——但对于你的示例数据,它会起作用吗? |
6
1
如果你要处理来自不同国家的电话号码,那几乎是不可能的。即使在同一个国家,长度也经常变化。如果你知道长度是多少(或者你想维护chrisw这样的列表),你可以在搜索公司的电话号码之前使用left(field,x)函数截断电话号码。注意,如果您正在执行联接,它可能会运行得慢得多,因为它必须在每一行上运行函数。 |
7
-1
如果没有进一步的信息,这将是不可能的:如果您的表是如上所述的结构,那么系统将无法知道哪个部分是基数,哪个部分是扩展名。因此它将返回“公司B”,以“+439”开头的任何(未知)号码。 编辑 (@markbooth) 我坚持我的主张,没有额外的信息是不可能的。只是为了更清楚:假设我们的数据库中有以下信息
这些数字的结构是+43(316)873-1,程序不知道。因此,如果一个号码+43316872133(+43(316)872133(带结构)正在呼叫(不在数据库中),则在没有进一步信息的情况下,您(因此您的软件:)无法判断它是否属于A公司。 唯一的解决方案是为公司维护“基数”,您可以对其进行简单的前缀搜索。 |