public class StringDistance {
/**
* 编程之美 计算字符串的相似度
* 我们定义一套操作方法来把两个不相同的字符串变得相同,具体的操作方法为:
* 1.修改一个字符(如把“a”替换为“b”);
* 2.增加一个字符(如把“abdd”变为“aebdd”);
* 3.删除一个字符(如把“travelling”变为“traveling”);
* 比如,对于“abcdefg”和“abcdef”两个字符串来说,我们认为可以通过增加/减少一个“g”的方式来达到目的。
* 上面的两种方案,都仅需要一次 。把这个操作所需要的次数定义为两个字符串的距离,而相似度等于“距离+1”的倒数。
* 也就是说,“abcdefg”和“abcdef”的距离为1,相似度 为1/2=0.5。
* 给定任意两个字符串,你是否能写出一个算法来计算它们的相似度呢?
*
* 解答:动态规划+备忘录
* 2012-11-04:主要思路还是递归。字符串记为A和B(当前比较的位置记为K,当前距离记为L),从第一个字符开始按位比较,分两种情况:
* 1、A和B在第K位的字符相等(L不变)。那好,各自向后移动,继续比较第K+1位
* 2、A和B在第K位的字符不相等(L=L+1)。采取递归,作三种操作,看哪种操作最后得到的距离最短:
* 一是A和B同时向后移动(相当于A和B同时删除这个字符),继续比较第K+1位
* 二是A移动B不移动,相当于A删除了这个字符,用剩余的字符与B作比较
* 三是A不移动B移动,相当于B删除了这个字符,用剩余的字符与A作比较
* 递归的好处就是可以递归得到这三种操作到最后得到的距离,哪个是最短
* 举个例子,A="abc",B="zbc"。我们可以一眼看出,采用第一种操作算得的距离最短(L=1)
* 但程序中要递归执行这另外两种操作并比较:
* A1="bc",B2="zbc" -->按位比较得到的L=1+3
* A2="abc",B2="bc" -->按位比较得到的L=1+3
* 因此程序会选择第一种操作,再接着进行第K+1位的比较
*/
private static int[][] record; //记录子问题的解,0表示子问题未求解
public static void main(String[] args) {
String strA = "abcd";
String[] strBB = {
"",
"z",
"a",
"ac",
"adc"
};
for (String strB : strBB) {
int distance = distanceBetween(strA, strB);
System.out.println(distance);
}
}
public static int distanceBetween(String strA, String strB) {
int distance = -1;
if (strA != null && strB != null) {
int lenA = strA.length();
int lenB = strB.length();
if (lenA == 0 && lenB == 0) {
distance = 0;
}
if (lenA != 0 && lenB == 0) {
distance = lenA;
}
if (lenA == 0 && lenB != 0) {
distance = lenB;
}
if (lenA != 0 && lenB != 0) {
record = new int[lenA + 1][lenB + 1];
char[] charArrayA = strA.toCharArray();
char[] charArrayB = strB.toCharArray();
distance = distanceHelp(charArrayA, charArrayB, 0, 0, lenA - 1, lenB - 1);
}
}
return distance;
}
//endA和endB是不变的,因此记录子问题的解可用record[beginA][beginB]来表示
public static int distanceHelp(char[] charArrayA, char[] charArrayB,
int beginA, int beginB, int endA, int endB) {
if (beginA > endA) { //递归出口:A从头到尾每个字符遍历完了,B有两种情况:
if (beginB > endB) { //1.B也同时遍历完了,说明这A=B
return 0;
} else {
return endB - beginB + 1; //2.B还没遍历完,那B剩下的长度就是两个字符串不同的地方,即距离
}
}
if (beginB > endB) {
if (beginA > endA) {
return 0;
} else {
return endA - beginA + 1;
}
}
int distance = -1;
if (charArrayA[beginA] == charArrayB[beginB]) {
distance = record[beginA + 1][beginB + 1];
if (distance == 0) {
distance = distanceHelp(charArrayA, charArrayB, beginA + 1, beginB + 1, endA, endB);
}
} else {
int d1 = record[beginA + 1][beginB];
if (d1 == 0) {
d1 = distanceHelp(charArrayA, charArrayB, beginA + 1, beginB, endA, endB);
}
int d2 = record[beginA][beginB + 1];
if (d2 == 0) {
d2 = distanceHelp(charArrayA, charArrayB, beginA, beginB + 1, endA, endB);
}
int d3 = record[beginA + 1][beginB + 1];
if (d3 == 0) {
d3 = distanceHelp(charArrayA, charArrayB, beginA + 1, beginB + 1, endA, endB);
}
distance = min(d1, d2, d3) + 1;
}
record[beginA][beginB] = distance;
return distance;
}
private static int min(int x, int...yy) {
int m = x;
for (int y : yy) {
if (y < m) {
m = y;
}
}
return m;
}
}
分享到:
相关推荐
本篇文章将深入探讨如何在Delphi环境下计算字符串的相似度,以及相关的技术细节。 Delphi是一种基于Object Pascal的集成开发环境,它提供了一套强大的工具和库,使得开发者能够高效地编写出高性能的应用程序。在...
使用Levenshtein Distance计算字符串相似度有以下几点需要注意: 1. **效率优化**:虽然基本的动态规划算法的时间复杂度是O(n*m),其中n和m分别是两个字符串的长度,但在实际应用中,可以采用空间优化技巧,如Wagner...
《使用Delphi实现Levenshtein算法:计算字符串相似度》 在信息技术领域,字符串处理是常见的任务之一,其中计算两个字符串的相似度是尤为重要的一个环节。Levenshtein算法,也称为编辑距离算法,就是用于衡量两个...
本篇文章将深入探讨如何使用DELPHI编程语言实现LCS(最长公共子序列)算法来衡量两个字符串的相似度。LCS算法是一种找出两个序列中最长的相同子序列的算法,它不考虑子序列的顺序,对于字符串而言,就是找到最长的...
在Python编程环境中,Levenshtein库是一个非常实用的工具,用于计算两个字符串之间的编辑距离。编辑距离,也称为Levenshtein距离,是衡量两个字符串差异的一种度量,定义为由一个字符串转换成另一个字符串最少的单...
在这个特定的案例中,易语言被用来编写算法,用于计算两个文本字符串之间的相似度。计算文本相似度通常是为了找出两段文本之间的共同部分,或者确定它们有多接近。这在信息匹配、文本分类、抄袭检测等方面有着广泛的...
在信息学奥赛中,计算字符串距离是一种常见的问题,它涉及到字符串处理和算法设计。这个问题的核心是衡量两个字符串之间的相似度或差异性。常见的方法有Levenshtein距离、Hamming距离、Jaccard相似度等。在这个...
本文将详细解析C#编程语言中实现的四种字符串相似度计算方法:编辑距离(Levenshtein Distance)、余弦相似性(Cosine Similarity)以及SimHash算法。 首先,编辑距离是一种衡量两个字符串之间差异的度量,它表示由...
- **编辑距离**:通过计算两个字符串转换成彼此所需的最少编辑操作(插入、删除、替换)数量,来评估它们的相似度。 - **最长公共子序列**:找出两个字符串的最长公共子序列,这也是衡量相似度的一种方式。 4. **...
总结来说,基于Hadoop的文本相似度计算涉及了分布式计算、文本处理和机器学习等多个方面,其中包括Hadoop的MapReduce编程模型、TF-IDF权重计算、向量空间模型的构建以及IKAnalyzer的中文分词技术。这些技术共同构成...
除此之外,还有一些专门为文本处理和字符串相似度匹配设计的库: - **Boost**: 提供了`boost::algorithm`库,包含字符串算法如`find_similar()`用于模糊匹配。 - **SeqAn**: 一个专门针对生物信息学序列处理的高...
本篇将深入探讨如何在Delphi中编写源代码来计算字符串的相似度。 首先,我们需要了解几种常见的字符串相似度算法: 1. **Levenshtein距离**:这个算法衡量的是通过插入、删除或替换操作将一个字符串转换成另一个...
这个项目以Java和JSP技术为基础,实现了一个计算两个字符串相似度的功能,并能显示运行时间,这有助于理解算法的效率。 首先,我们需要了解字符串相似度的计算方法。常见的算法有Levenshtein距离、Jaccard相似度、...
- `similar_text()`函数并不总是最精确的方法来计算字符串相似度,特别是在处理多字节字符(如中文字符)时,由于字符编码的原因,结果可能不完全准确。 - `levenshtein()`函数虽然速度较快,但可能不如`similar_...
为了实际应用这些方法,我们可以创建一个类库,包含各种计算字符串相似度的静态方法,并提供友好的API供其他项目调用。此外,如果需要提高性能,还可以考虑使用多线程或异步处理,特别是在处理大量字符串比较时。 ...
标题中提到的“1.7编程基础之字符串(30题)--题目 有链接.pdf”指明了这份资料是一本关于编程基础的题集,专注于字符串相关的编程题目,并且这些题目可以在提供的链接中找到。由于文件内容中提到了多个编程题目,我们...
总之,最小编辑距离算法是计算字符串相似度的一种有效方法,通过动态规划实现,具有较高的效率和广泛的应用价值。在Java编程中,`EditDistance.java`文件所包含的实现可以帮助开发者在各种需要字符串比较的场景下...
项目提供的源代码"基于C++实现的通过动态规划查找最长公共子序列计算字符串之间相似度"中,应该详细展示了如何利用C++语法来实现这个动态规划算法。通过阅读和分析这段代码,我们可以学习到C++的编程技巧,以及如何...
综上所述,易语言文本相似度判断模块涉及到了多个层次的编程技术,包括字符串处理、向量化、相似度计算算法以及模块化编程思想。通过学习和实践这个模块,开发者能够掌握文本相似度判断的关键步骤,并在实际项目中...
Levenshtein距离算法是一种衡量两个字符串相似度的数学方法,由俄国科学家Vladimir Levenshtein在1965年提出。这个算法通过计算将一个字符串转换成另一个字符串所需的最少单字符编辑(插入、删除或替换)次数来评估...