Delphi Spell Checker组件.
两年前,我在Python中找到并使用了Peter Norvig at his website的拼写纠正器代码.但表现似乎并不高.非常有趣的是,最近在他的网页列表中附加了更多实现相同任务的语言.
[a + c + b for a,b in splits for c in alphabet]
如何将其翻译成delphi?
我对SO的Delphi专家将如何使用相同的理论并使用一些合适的线和可能的平庸或更好的性能执行相同的任务感兴趣.这不是为了贬低任何语言,而是要学会比较他们如何以不同方式实现任务.
非常感谢提前.
[编辑]
我将引用Marcelo Toledo谁贡献C版,说“……虽然本文[C版]的目的是展示算法,而不是突出Python …”.虽然他的C版本排在第二位,但根据他的文章,他的版本在字典文件庞大时性能很高.因此,这个问题不是强调任何语言,而是要求delphi解决方案并且它根本不适合竞争,尽管Peter在指导Google Research方面具有影响力.
[更新]
我被大卫的建议所启发,并研究了彼得页面的理论和惯例.这是一个非常粗糙和低效的例程,与其他语言略有不同,我的是GUI.我是Delphi的初学者和学习者,我不敢发布我的完整代码(写得不好).我将概述我是如何做到的.欢迎您的评论,以便改进例行程序.
我的硬件和软件都很旧.这对我的工作来说已经足够了(我的专业不在于计算机或程序相关)
AMD Athlon Dual Core Processor 2.01 Ghz,480 Memory Windows XP SP2 IDE Delphi 7.0
这是“正确”单词处理时间的快照和记录.
我尝试了Gettickcount,Tdatetime和Queryperformancecounter来跟踪正确的单词时间,但gettickcount和Tdatetime将为每个检查输出o ms,所以我必须使用
QueryPerformanceCounter的.也许还有其他方法可以更精确地做到这一点.
总行数为72,不包括记录检查时间的功能.如上所述,Marcelo的行数可能不是标准.该帖子讨论了如何以不同方式完成任务. SO的Delphi专家当然会使用最小的线来实现最佳性能.
procedure Tmajorform.FormCreate(Sender: TObject); begin loaddict; end; procedure Tmajorform.loaddict; var fs: TFilestream; templist: TStringlist; p1: tperlregex; w1: string; begin //load that big.txt (6.3M,is Adventures of Sherlock Holmes) //templist.loadfromstream //Use Tperlregex to tokenize ( I used regular expression by [Jan Goyvaerts][5]) //The load and tokenize time is about 7-8 seconds on my machine,Maybe there are other ways to //speed up loading and tokenizing. end; procedure Tmajorform.edits1(str: string); var i: integer; ch: char; begin // This is to simulate Peter's page in order to fast generate all possible combinations. // I do not know how to use set in delphi. I used array. // Peter said his routine edits1 would generate 494 elements of 'something'. Mine will // generate 469. I do not know why. Before duplicate ignore,mine is over 500. After setting // duplicate ignore,there are 469 unique elements for 'something'. end; procedure Tmajorform.correct(str: string); var i,j: integer; begin //This is a loop and binary search to add candidate word into list. end; procedure Tmajorform.Button2Click(Sender: TObject); var str: string; begin // Trigger correct(str: string); end;
它似乎通过Tfilestream它可以增加1-2秒的负载.我尝试使用CreateFileMapping方法但失败了,看起来有点复杂.也许还有其他方法可以快速加载大文件.因为考虑到语料库的可用性,这个big.txt不会很大,所以应该有更有效的方法来加载更大和更大的文件.
另一点是Delphi 7.0没有内置的正则表达式.我看看在Perter的页面上进行拼写检查的其他语言,它们主要是直接调用它们的内置正则表达式.当然,真正的专家不需要任何内置的类或库,可以自己构建.对于初学者来说,一些类或库是方便的.
欢迎您的评论.
[更新]
我继续研究并进一步包括edits2功能(编辑距离2).这将增加大约另外12行代码.彼得说编辑距离2几乎涵盖了所有可能性. ‘某事’将有114,324种可能性.我的功能将为它生成102,727个独特的可能性.当然,建议的单词也会包含更多内容.
如果使用edits2,则响应修正的时间显然会延迟,因为它会使数据增加约200倍.但我发现一些建议的更正显然是不可能的,因为打字员不会输入将在长期更正的单词列表中的错误单词.因此,如果big.txt文件足够大以包含更多正确的单词,则编辑距离1将更好.
以下是跟踪编辑2正确时间的快照.
解决方法
每个分裂项都是一个元组,它被解压缩到a和b中.每个字母表项都放在一个名为c的变量中.然后将3个变量连接起来,假设它们是字符串.列表推导表达式的结果是包含形式a c b的元素的列表,笛卡尔积中每个项的一个元素.
在Python中,它可以被等效地编写为
res = [] for a,b in splits: for c in alphabets: res.append(a + c + b)
在德尔福,它会
res := TStringList.Create; for split in splits do for c in alphabets do res.Add(split.a + c + split.b);
我建议你阅读Python list comprehensions以更好地理解这个非常强大的Python功能.