C#人名检查与匹配算法

C#人名检查与匹配算法,c#,string-matching,spell-checking,C#,String Matching,Spell Checking,是否有一个算法或C#库来确定人名是否正确,如果不正确,找到最接近的匹配 我找到了字符串匹配的算法,比如Levenshtein的距离算法,但它们都检查一个字符串和另一个字符串之间的匹配,我想检查一个名称和所有可能的英语名称之间的匹配(例如),以检查名称是否写错了 例如: 有人插入了名字“Giliam”,而它应该是“william”。我想知道是否有任何算法(或一组算法)来检测错误并提出更正 我想到的所有解决方案都涉及到一个巨大的人名字典的实现,并使用它逐个检查每个输入名称匹配的正确性。。。对我来说,

是否有一个算法或C#库来确定人名是否正确,如果不正确,找到最接近的匹配

我找到了字符串匹配的算法,比如Levenshtein的距离算法,但它们都检查一个字符串和另一个字符串之间的匹配,我想检查一个名称和所有可能的英语名称之间的匹配(例如),以检查名称是否写错了

例如: 有人插入了名字“Giliam”,而它应该是“william”。我想知道是否有任何算法(或一组算法)来检测错误并提出更正

我想到的所有解决方案都涉及到一个巨大的人名字典的实现,并使用它逐个检查每个输入名称匹配的正确性。。。对我来说,这听起来很恐怖,所以我想寻求更好的方法


谢谢。

实际上,您要问的是如何使用给定的词典创建拼写检查器。一种不需要查找和测试列表中每一个可能条目的方法是做与问题相反的事情:从用户输入中生成一个可能的排列列表,并测试其中的每一个,看看它们是否在列表中。这是一个更容易处理的问题

例如,您可以使用这样的函数生成一个“编辑”可以从给定单词中获得的每个可能的排列:

static HashSet GenerateEdits(字符串字)
{
//使案件正常化
word=word.ToLower();
var splits=新列表();
for(int i=0;i0)
{
ret.Add(cur.Item1+cur.Item2.子字符串(1));
}
}
//所有转置的可能性
foreach(拆分中的变量cur)
{
如果(当前项目2.长度>1)
{
ret.Add(当前项1+当前项2[1]+当前项2[0]+当前项2.子字符串(2));
}
}
var letters=“abcdefghijklmnopqrstuvxyz”;
//所有替换字符
foreach(拆分中的变量cur)
{
如果(当前项2.Length>0)
{
foreach(字母中的var字母)
{
ret.Add(当前项1+字母+当前项2.子字符串(1));
}
}
}
//所有插入字符
foreach(拆分中的变量cur)
{
foreach(字母中的var字母)
{
ret.Add(当前项目1+字母+当前项目2);
}
}
返回ret;
}
然后练习代码,看看给定的用户输入是否可以轻松地卷积为这些条目之一。可以通过加权平均值或简单地向用户呈现可能性列表来找到最佳匹配:

//示例文件来自:
// https://raw.githubusercontent.com/smashew/NameDatabases/master/NamesDatabases/first%20names/all.txt
字符串源=@“all.txt”;
var name=newhashset();
使用(var sr=新的StreamReader(源))
{
弦线;
而((line=sr.ReadLine())!=null)
{
name.Add(line.ToLower());
}
}
var userEntry=“Giliam”;
var=false;
if(names.Contains(userEntry.ToLower()))
{
Console.WriteLine(“输入的“+userEntry+”值看起来不错”);
发现=真;
}
如果(!找到)
{
//尝试编辑一个远离用户条目的编辑
foreach(GenerateEdits中的var测试(userEntry))
{
if(name.Contains(test))
{
Console.WriteLine(test+”是“+userEntry”的一种可能性);
发现=真;
}
}
}
如果(!找到)
{
//尝试编辑两个远离用户条目的编辑
foreach(GenerateEdits中的var测试(userEntry))
{
foreach(生成项中的var test2(测试))
{
if(name.Contains(test))
{
Console.WriteLine(test+”是“+userEntry”的一种可能性);
发现=真;
}
}
}
}
kiliam是Giliam的一种可能性
利利亚姆是吉利亚姆的一个可能
viliam是Giliam的一个可能性
wiliam是Giliam的一个可能性

当然,既然你说的是人名,你最多只能提出一个建议,并为奇怪的拼写和你从未见过的东西的拼写做好准备。如果你想支持其他语言,那么<>代码> GeaseTebug <代码>变得更加复杂,因为你认为什么是“键入”< /p>人类可以随便称为任何东西。坦率地说,任何试图“纠正”姓名的行为都更有可能通过“纠正”书写正确的姓名而引发问题。同样,少数民族和移民也可能不成比例地以这种方式得到“纠正”,这在政治上和社会上都是愚蠢的尝试,我认为。同样,永远不要试图对名字实施限制,比如最小字符,甚至是单独的名字/姓的概念。见鬼,连我的名字都经常被“更正”(改成马克),真让人讨厌!你怎么知道应该是“威廉”。也可能是“吉利安”@OlivierJacot Descombes,也可能是