本篇文章给大家谈谈如何在Delphi中实现Levenshtein距离?,以及delphilib的知识点,同时本文还将给你拓展c–如何确定普通话的Levenshtein距离?、Damerau-Leven
本篇文章给大家谈谈如何在Delphi中实现Levenshtein距离?,以及delphi lib的知识点,同时本文还将给你拓展c – 如何确定普通话的Levenshtein距离?、Damerau-Levenshtein距离实现、Delphi : WebBrowser、MSHTML在Delphi中的使用、delphi-7 – 如何在delphi中获取appdata文件夹路径等相关知识,希望对各位有所帮助,不要忘了收藏本站喔。
本文目录一览:- 如何在Delphi中实现Levenshtein距离?(delphi lib)
- c – 如何确定普通话的Levenshtein距离?
- Damerau-Levenshtein距离实现
- Delphi : WebBrowser、MSHTML在Delphi中的使用
- delphi-7 – 如何在delphi中获取appdata文件夹路径
如何在Delphi中实现Levenshtein距离?(delphi lib)
我本着回答您自己问题的精神发布此帖子。
我的问题是:如何在Delphi中实现Levenshtein算法来计算两个字符串之间的编辑距离,如此处所述?
只是关于性能的注释:这件事非常快。在我的台式机(2.33 Ghz双核,2GB内存,WinXP)上,我可以在不到一秒钟的时间内运行100K字符串数组。
答案1
小编典典function EditDistance(s, t: string): integer;var d : array of array of integer; i,j,cost : integer;begin { Compute the edit-distance between two strings. Algorithm and description may be found at either of these two links: http://en.wikipedia.org/wiki/Levenshtein_distance http://www.google.com/search?q=Levenshtein+distance } //initialize our cost array SetLength(d,Length(s)+1); for i := Low(d) to High(d) do begin SetLength(d[i],Length(t)+1); end; for i := Low(d) to High(d) do begin d[i,0] := i; for j := Low(d[i]) to High(d[i]) do begin d[0,j] := j; end; end; //store our costs in a 2-d grid for i := Low(d)+1 to High(d) do begin for j := Low(d[i])+1 to High(d[i]) do begin if s[i] = t[j] then begin cost := 0; end else begin cost := 1; end; //to use "Min", add "Math" to your uses clause! d[i,j] := Min(Min( d[i-1,j]+1, //deletion d[i,j-1]+1), //insertion d[i-1,j-1]+cost //substitution ); end; //for j end; //for i //now that we''ve stored the costs, return the final one Result := d[Length(s),Length(t)]; //dynamic arrays are reference counted. //no need to deallocate themend;
c – 如何确定普通话的Levenshtein距离?
我们想扩展这个系统来处理以Unicode表示的普通话中文表意文字.我们如何在类似汉字之间执行Levenshtein距离计算?
解决方法
但是,由于您的问题具体涉及个人角色之间的编辑距离,我认为需要采用不同的方法,确实可能非常困难.
首先,您必须将每个字符表示为组成的组件/笔画的顺序.有两个问题:
>某些组件由更小的组件组成,所以如何将角色分解为“原子”组件并不是唯一定义的.如果你做到单个笔画的水平,你需要描述每一个笔画(角色,形状,方向等等).我不认为任何人都这样做(如果有人告诉我,我会最感兴趣的).
>您需要将笔画或组件放在一个顺序中.明显的候选人是字典的规范笔画顺序,在词典中有描述,甚至有字典网站都有动画笔画顺序图.然而,我知道的数据源(对于日语),生成这些动画作为位图图形的序列;我从来没有看到适用于编辑距离计算的表单中的人物或机器可读代码来代表笔画序列(甚至单个笔画的名称).
可以尝试一个最后一件事是渲染字符字形,并根据需要改变多少个像素(或向量)将一个字符转换为另一个字符来计算编辑距离.我曾经在OCR修正后的背景下做了拉丁字符和字符组合(以像素为单位),结果相当令人鼓舞.
对larsmans的一个快速回答如下:Unicode标准定义了两个相关概念(下面我参考6.0 version,chapter 12):
>基于激进和中风计数的指标.每个汉字由几个组成部分组成,其中一个是激进的.激进/笔触计数索引是由根基(即,共享相同基团组合在一起的所有字符)排序的字符列表,并且每个激进特定组在内部根据字符的其余部分中使用的笔画数进行排序.不幸的是,即使这并不是唯一的定义 – 有不同传统词汇定义不同的字符,笔画计数也很难.以下是Unicode标准的内容:
To expedite locating specific Han ideographic characters in the code charts,radical-stroke indices are provided on the Unicode web site. […]
The most influential authority for radical-stroke information is the eighteenth-century
KangXi dictionary,which contains 214 radicals. The main problem in using KangXi radicals today is that many simplified characters are difficult to classify under any of the 214
KangXi radicals. As a result,varIoUs modern radical sets have been introduced. None,however,is in general use,and the 214 KangXi radicals remain the best kNown. […]
The Unicode radical-stroke charts are based on the KangXi radicals. The Unicode Standard
follows a number of different sources for radical-stroke classification. Where two sources
are at odds as to radical or stroke count for a given character,the character is shown in both positions in the radical-stroke charts.
注意,即使我们假设激进/中风指数是明确和正确的,它不足以将字符转换成一个组件序列的信息源,因为完全描述的字符的唯一组件是激进.
>表意描述序列(第12.2节):Unicode定义了字符的基本组件的代码点(大多数可以自己被用作独立字符),并且有一些代码点用于将它们粘合在一起以形成描述的组件序列组成更复杂的人物.所以这样做的方式类似于组合字符,但有重要的区别:
>组件的顺序不是唯一定义的
>这种序列的渲染机制没有定义
>没有从普通字符到对应的表意描述序列的映射(虽然标准提到这种映射在某种程度上存在于用于编译汉字符集的源中).
标准表明,表意描述序列用于描述没有由任何现有代码点表示的复杂或罕见的特征;但是它明确地阻止使用描述序列代替普通字符:
In particular,Ideographic Description Sequences should not be used to provide alternative graphic representations of encoded ideographs in data interchange. Searching,collation,and other content-based text operations would then fail.
Damerau-Levenshtein距离实现
我正在尝试在JS中创建damerau-levenshtein距离函数。
我在WIkipedia上找到了关于该算法的描述,但是他们没有实现它。它说:
要设计适当的算法来计算不受限制的Damerau–Levenshtein距离,请注意,始终存在最佳的编辑操作序列,在此之后,一旦转置的字母就永远不会被修改。因此,我们只需要考虑两种以上修改子串的对称方式:(1)转置字母并在它们之间插入任意数量的字符,或者(2)删除一系列字符并转置在删除后变为相邻的字母。这个想法的直接实现给出了三次复杂度的算法:O
\ left(M \ cdot N \ cdot \ max(M,N)\
right),其中M和N是字符串长度。利用Lowrance和Wagner的思想,[7]在最坏的情况下,可以将这种幼稚算法改进为O \ left(M \
cdot N \ right)。有趣的是,可以修改bitap算法以处理换位。有关此类修改的示例,请参见[1]的信息检索部分。https://zh.wikipedia.org/wiki/Damerau%E2%80%93Levenshtein_distance
[1]部分指向http://acl.ldc.upenn.edu/P/P00/P00-1037.pdf,这对我来说更加复杂。
如果我正确理解了这一点,那么创建一个实现就不那么容易了。
这是我当前使用的levenshtein实现:
levenshtein=function (s1,s2) {
// discuss at: http://phpjs.org/functions/levenshtein/
// original by: Carlos R. L. Rodrigues (http://www.jsfromhell.com)
// bugfixed by: Onno Marsman
// revised by: Andrea Giammarchi (http://webreflection.blogspot.com)
// reimplemented by: Brett Zamir (http://brett-zamir.me)
// reimplemented by: Alexander M Beedie
// example 1: levenshtein('Kevin van Zonneveld','Kevin van Sommeveld');
// returns 1: 3
if (s1 == s2) {
return 0;
}
var s1_len = s1.length;
var s2_len = s2.length;
if (s1_len === 0) {
return s2_len;
}
if (s2_len === 0) {
return s1_len;
}
// BEGIN STATIC
var split = false;
try {
split = !('0')[0];
} catch (e) {
// Earlier IE may not support access by string index
split = true;
}
// END STATIC
if (split) {
s1 = s1.split('');
s2 = s2.split('');
}
var v0 = new Array(s1_len + 1);
var v1 = new Array(s1_len + 1);
var s1_idx = 0,s2_idx = 0,cost = 0;
for (s1_idx = 0; s1_idx < s1_len + 1; s1_idx++) {
v0[s1_idx] = s1_idx;
}
var char_s1 = '',char_s2 = '';
for (s2_idx = 1; s2_idx <= s2_len; s2_idx++) {
v1[0] = s2_idx;
char_s2 = s2[s2_idx - 1];
for (s1_idx = 0; s1_idx < s1_len; s1_idx++) {
char_s1 = s1[s1_idx];
cost = (char_s1 == char_s2) ? 0 : 1;
var m_min = v0[s1_idx + 1] + 1;
var b = v1[s1_idx] + 1;
var c = v0[s1_idx] + cost;
if (b < m_min) {
m_min = b;
}
if (c < m_min) {
m_min = c;
}
v1[s1_idx + 1] = m_min;
}
var v_tmp = v0;
v0 = v1;
v1 = v_tmp;
}
return v0[s1_len];
}
构建这种算法的想法是什么,如果您认为它太复杂了,那么我该怎么做才能使“ l”(L小写)和“ I”(i大写)之间没有区别。
Delphi : WebBrowser、MSHTML在Delphi中的使用
总结
以上是小编为你收集整理的Delphi : WebBrowser、MSHTML在Delphi中的使用全部内容。
如果觉得小编网站内容还不错,欢迎将小编网站推荐给好友。
delphi-7 – 如何在delphi中获取appdata文件夹路径
begin Winexec(PAnsichar('%appdata%\TEST.exe'),sw_show); end; end.
但没有工作.
@R_301_5609@
uses ...,SysUtils; function GetPathToTestExe: string; begin Result := SysUtils.GetEnvironmentvariable('APPDATA'); if Result <> '' then Result := IncludeTrailingPathDelimiter(Result) + 'TEST.exe'; end;
uses ...,Windows; var Path: string; begin Path = GetPathToTestExe; if Path <> '' then WinExec(PAnsiChar(Path),SW_SHOW); end;
或者:
uses ...,SysUtils,Windows; function GetPathToTestExe: string; var Path: array[0..MAX_PATH+1] of Char; begin if ExpandEnvironmentStrings('%APPDATA%',Path,Length(Path)) > 1 then Result := IncludeTrailingPathDelimiter(Path) + 'TEST.exe' else Result := ''; end;
获取APPDATA文件夹路径的更可靠(和官方)方式是使用SHGetFolderPath()(或Vista上的SHGetKNownFolderPath()):
uses ...,Windows,SHFolder; function GetPathToTestExe: string; var Path: array[0..MAX_PATH] of Char; begin if SHGetFolderPath(0,CSIDL_APPDATA,SHGFP_TYPE_CURRENT,Path) = S_OK then Result := IncludeTrailingPathDelimiter(Path) + 'TEST.exe' else Result := ''; end;
但是,无论如何,自Windows 95以来,WinExec()已被弃用,你真的应该使用CreateProcess()代替:
uses ...,Windows; var Path: String; si: TStartupInfo; pi: TProcessinformation; Path := GetPathToTetExe; if Path <> '' then begin ZeroMemory(@si,SizeOf(si)); si.cb := SizeOf(si); si.dwFlags := STARTF_USESHOWWINDOW; si.wShowWindow := SW_SHOW; if CreateProcess(nil,PChar(Path),nil,FALSE,@si,pi) begin //... CloseHandle(pi.hThread); CloseHandle(pi.hProcess); end; end;
我们今天的关于如何在Delphi中实现Levenshtein距离?和delphi lib的分享就到这里,谢谢您的阅读,如果想了解更多关于c – 如何确定普通话的Levenshtein距离?、Damerau-Levenshtein距离实现、Delphi : WebBrowser、MSHTML在Delphi中的使用、delphi-7 – 如何在delphi中获取appdata文件夹路径的相关信息,可以在本站进行搜索。
本文标签: