背景:我有一个庞大的人员数据库,我想查找重复项,这比看起来更难。我已经对名称(通常以不同方式拼写),出生日期等进行了大量比较。当两个配置文件看起来与匹配算法足够相似时,它们将呈现给将要判断的操作员。
大多数个人资料都附有多个电话号码,所以我想用它们来查找重复项。它们可以输入为“001-555-123456”,也可以输入“555-123456”,“555-123456-7-8”,“555-123456在晚上给我打电话”或任何你可能想到的。 我的第一个想法是剥离所有非数字字符并获得“最长的公共子字符串”。 有许多算法可以找到集合中最长的公共子字符串。 但每当我比较两个配置文件A和B时,我就有两组电话号码。我想找到集合A中的字符串和集合B中的字符串之间最长的公共子字符串。 能帮我找到这样的算法吗? 我通常用PHP编程,只有SQL的解决方案会更好,但任何其他语言都可以。
答案 0 :(得分:1)
正如Voitcus之前所说,在开始比较或寻找重复数据之前,您必须先清理数据。电话号码应遵循严格的模式。对于与模式不匹配的数字,请尝试将其调整为它。然后,您就可以查找重复项了。
此外,你应该在坚持之前进行数据清理,也许是在一个单独的专栏中。在寻找重复项时,您不必关心它...只是为了避免性能峰值。
像php中的levenshtein或similar_text()这样的算法很不适合这个用例。
答案 1 :(得分:0)
在我看来,最好的方法是从包含电话号码的文本中删除所有非数字字符。你可以通过多种方式做到这一点,一些正则表达式是最好的,但见下文。
然后,如果可能,您可以找到国家/地区方向代码,如果用户具有其位置国家/地区。如果没有,则假定为default并添加到字符串。这可能与城市相同。您可以尝试查看一个人的生活,邮政编码等。
在此结尾处,您应该有统一的电话号码,可以轻松比较。
另一种方法是将字符串与已删除的国家/地区(和城市)代码进行比较。
关于搜索“最长公共子字符串”:这样过滤的数字是相同的,但是你可能需要它,例如。如果有人打字“请在下午6点之后给我打电话”。如果您确定电话号码始终在开头,那么没有人输入类似555-SUPERMAN的内容(转换为555-78737626),也可以删除最后一个字母数字字符后面的所有字符(以及此字符)
还有可能在SQL语句中过滤此类数据。考虑像SELECT ..., [your trimming function(phone_number)] AS trimmed_phone WHERE (trimmed_phone is not numerical characters only) GROUP BY trimmed_phone
这样的东西。如果修剪功能只删除空格和特殊分隔符,例如-
,+
,.
(通常在德国使用),,
或许等,此查询将离开修剪但包含非数字字符的所有电话号码 - 查看结果,可能主要是数字和字母。他们中有多少人?也许他们有共同点?也许你可以过滤一些典型的短语?
如果此类查询的结果不是很多,那么手动操作会更容易吗?