由于本人对算法理解的重大失误,造成原来写的程序有重大BUG。特此向各位道歉来了,呵呵
今天又将算法看了一遍,终于理解其精髓
下面是主要的实现代码,献丑了
首先是初始化一个boolean数组,存放各个字符是否匹配的:
<!----> public static boolean[][] getCompareBooleanArray(String source,
String compareTo) {
boolean[][] comps;
if (compareTo == null || source == null) {
throw new IllegalArgumentException("必须设置完两个文本后再进行初始化");
}
comps = new boolean[compareTo.length()][source.length()];
for (int i = 0; i < compareTo.length(); i++) {
for (int j = 0; j < source.length(); j++) {
comps[i][j] = compareTo.charAt(i) == source.charAt(j);
// System.out.print(comps[i][j] + "\t");
}
// System.out.println();
}
return comps;
}
这个实现基本上没什么说的,就这样
接着是一个根据这个boolean数组初始化一个int矩阵的函数,这个函数就对应寻找最大匹配路径的函数
<!----> public static int[][] getSetpPathArr(boolean[][] barr) {
int[][] iarr = new int[barr.length][barr[0].length];
for (int i = barr.length - 1; i >= 0; i--) {
for (int j = barr[i].length - 1; j >= 0; j--) {
int v_i_j = barr[i][j] ? 1 : 0;
int n_i_1_j_1 = i + 1 >= iarr.length || j + 1 >= iarr[i].length ? 0
: iarr[i + 1][j + 1];
int n_i_1_j = i + 1 >= iarr.length ? 0 : iarr[i + 1][j];
int n_i_j_1 = j + 1 >= iarr[i].length ? 0 : iarr[i][j + 1];
int v_n_1_1 = v_i_j + n_i_1_j_1;
iarr[i][j] = v_n_1_1 > n_i_1_j ? v_n_1_1 > n_i_j_1 ? v_n_1_1
: n_i_j_1 : n_i_1_j > n_i_j_1 ? n_i_1_j : n_i_j_1;
}
}
return iarr;
}
根据算法的解释,从下往上,从右向左计算每个格子
对应寻找最优路径的函数,也是初始化一个int[][]
<!----> public static int[][] getMinSetpArr(int[][] miarr, boolean[][] barr) {
int[][] iarr = new int[miarr.length][miarr[0].length];
for (int i = iarr.length - 1; i >= 0; i--) {
for (int j = iarr[i].length - 1; j >= 0; j--) {
if (barr[i][j]) {
iarr[i][j] = getV(iarr, i + 1, j + 1) + 1;
} else if (getV(miarr, i, j + 1) >= getV(miarr, i + 1, j)) {
iarr[i][j] = getV(iarr, i, j + 1);
} else {
iarr[i][j] = getV(iarr, i + 1, j) + 1;
}
}
}
return iarr;
}
这样就相应对应了算法中讲的那三个矩阵。
当然了,上面有调用到一个叫getV的方法,方法很简单
<!----> private static int getV(int[][] arr, int i, int j) {
if (i >= arr.length || j >= arr[i].length) {
return 0;
}
return arr[i][j];
}
分别初始化完这三个数组后对结果进行计算。
<!---->boolean[][] barr = getCompareBooleanArray(source, compareTo);
int[][] miarr = getSetpPathArr(barr);
int[][] diarr = getMinSetpArr(miarr, barr);
先找出从顶点出发,下一步该走的那几个点:
<!---->List<Point> points = new ArrayList<Point>();
int maxJ = -1;
for (int i = 0; i < barr.length; i++) {
int tempMaxJ = -1;
for (int j = 0; j < barr[i].length; j++) {
if (j > maxJ && maxJ != -1) {
break;
}
if (barr[i][j]) {
if (tempMaxJ == -1) {
tempMaxJ = j;
}
points.add(new Point(i, j));
}
}
if (tempMaxJ != -1) {
maxJ = tempMaxJ;
}
}
找出可能的最大最优匹配路径,这个可能会有几条路径,核心代码:
<!---->int max = 0;
int minSetp = -1;
for (Point point : points) {
if (miarr[point.getX()][point.getY()] > max) {
max = miarr[point.getX()][point.getY()];
}
}
for (Point point : points) {
if (minSetp == -1) {
minSetp = diarr[point.getX()][point.getY()];
} else if (miarr[point.getX()][point.getY()] >= max
&& diarr[point.getX()][point.getY()] < minSetp) {
minSetp = diarr[point.getX()][point.getY()];
}
}
List<Point> willRemove = new ArrayList<Point>();
for (Point point : points) {
if (miarr[point.getX()][point.getY()] < max
|| diarr[point.getX()][point.getY()] > minSetp) {
willRemove.add(point);
}
}
points.removeAll(willRemove);
willRemove.clear();
找到这里,最大匹配并且最优匹配的路径就找到了
下面就是要计算差异了,基本和我上次写的计算差异的方法差不多
<!---->List<TextDiff> diffs = new ArrayList<TextDiff>();
if (points.size() >= 1) {
Point startPoint = points.get(0);
points.clear();
if (startPoint.getX() != 0) {
diffs.add(new TextDiff(TextDiff.TYPE_INSERTED, 0, startPoint
.getX()));
}
if (startPoint.getY() != 0) {
diffs.add(new TextDiff(TextDiff.TYPE_DELETED, 0, startPoint
.getY()));
}
Point next = getNext(startPoint, miarr, diarr, barr);
while (next != null) {
if (!barr[startPoint.getX()][startPoint.getY()]) {
startPoint = new Point(startPoint.getX() + 1, startPoint
.getY() + 1);
}
if (startPoint.getX() != next.getX() - 1
|| startPoint.getY() != next.getY() - 1) {
diffs.add(new TextDiff(TextDiff.TYPE_INSERTED, startPoint
.getX(), next.getX() - startPoint.getX()));
diffs.add(new TextDiff(TextDiff.TYPE_DELETED, startPoint
.getY(), next.getY() - startPoint.getY()));
}
startPoint = next;
next = getNext(startPoint, miarr, diarr, barr);
}
if (startPoint.getX() != barr.length) {
diffs.add(new TextDiff(TextDiff.TYPE_INSERTED, startPoint
.getX(), barr.length - startPoint.getX()));
}
if (startPoint.getY() != barr[0].length) {
diffs.add(new TextDiff(TextDiff.TYPE_DELETED,
startPoint.getY(), barr[0].length - startPoint.getY()));
}
}
大功告成。。。。。
源码:http://www.blogjava.net/Files/phyeas/src.zip
分享到:
相关推荐
2. **Java文本比较算法**:在Java中,实现文本比对通常涉及字符串操作,如`equals()`、`contains()`等方法,但更复杂的比对需求会使用特定的算法。例如,Jaccard相似度、余弦相似度、Levenshtein距离等。 3. **...
在这个项目中,我们将深入探讨如何使用C++实现KNN算法来对文本进行分类。 KNN算法的基本思想是:对于一个新的未知类别数据点,我们将其与已知类别的数据集中的所有数据点进行比较,找出与其最接近的K个点,然后根据...
提供的“Dynamic Programming Tutorial.mht”和“Advanced Dynamic Programming Tutorial.mht”文件很可能是关于动态规划的深入教程,可以帮助读者进一步理解和掌握这两种文本比较算法的实现细节。
在提供的压缩包文件中,"LD文本比较(main).txt"很可能是实现LD算法的代码主体,而"BXH.txt"、"ZXM.txt"、"ZXM.h.txt"、"BXH.h.txt"可能是辅助代码文件,比如头文件和额外的功能模块。这些文件可能包含了算法的具体...
在"易语言文本相似度算法"这个主题中,我们主要关注的是如何使用易语言来实现文本相似度的计算。文本相似度算法是自然语言处理领域的一个重要组成部分,它用于衡量两个或多个文本之间的相似程度。 文本相似度算法...
【基于机器学习的中文文本分类算法的研究与实现】 随着大数据时代的快速发展,文本信息数据量急剧增加,为了从海量信息中快速有效地获取有价值的内容,文本分类技术成为了一个关键领域。新闻文本作为信息传播的重要...
### 文本分类算法的比较研究 #### 摘要概览与研究背景 随着信息技术的飞速发展,互联网上的数据量急剧增长,如何有效管理和利用这些海量信息成为了研究的热点。文本分类(Text Categorization,简称TC)作为信息...
研究文本压缩算法比较,对于优化存储成本和提高数据传输效率有重要意义。在文本压缩领域,有多种算法被提出和广泛研究,其中包括Huffman编码、LZ系列算法(如LZ77、LZ78和LZW)等。 首先,Huffman编码是根据字符...
### 文本聚类算法的比较和分析 #### 摘要 本文主要针对几种常见的文本聚类算法进行了详细的介绍,并从各个算法的适用场景、初始参数的影响、算法的终止条件以及对噪声数据的敏感程度等方面进行了全面的比较与分析。...
在算法实现过程中,引入了一系列专业术语以简化后续的讨论。例如,“2维词组”指的是由两个相邻单词组成的组合,这是算法处理的基本单元。通过对这些词组的统计与排序,算法能够揭示文本数据中隐藏的词汇共现模式,...
2. **KMP算法**:由Knuth、Morris和Pratt提出的改进方法,通过构造失败函数避免了不必要的字符比较。当匹配过程中出现不匹配时,可以根据失败函数快速跳过已匹配的部分,提高效率。 3. **Boyer-Moore算法**:利用了...
本文将深入探讨如何在C#中实现文本对比算法,以比较两个字符串的不同,并了解如何利用这些差异进行实际应用。 首先,文本对比的基本目标是识别两个文本之间的异同,这在版本控制、文档编辑、代码审查等场景中非常...
常用文本聚类算法java实现源码.zip常用文本聚类算法java实现源码.zip常用文本聚类算法java实现源码.zip常用文本聚类算法java实现源码.zip
1、内容概要:本资源主要基朴素贝叶斯算法实现新闻分类,适用于初学者学习文本分类使用。 2、新闻分类源码实现过程:将数据集划分为训练集和测试集;使用jieba模块进行分词,词频统计,停用词过滤,文本特征提取,将...
2. 比较和排序:算法可能还需要对找到的重复项进行比较,以确定它们是否完全一致,或者仅是相似但不相同。 3. 数据结构优化:为了高效存储和检索,算法可能会使用特定的数据结构来管理字符串集合,以减少不必要的...
在自然语言处理领域,文本聚类是一种常见的无监督学习方法,...总的来说,Java实现KMeans文本聚类涉及到数据预处理、向量化、聚类算法实现和性能优化等多个方面,理解这些知识点对于提升文本分析项目的效果至关重要。
在给定的代码示例中,你可以看到如何实现simHash算法,从而计算两个中文文本的相似度。 接下来,我们讨论海明距离。海明距离是衡量两个字符串差异程度的度量,对于simHash算法而言,它用于比较两个哈希值的相似度。...
在Java实现kMeans文本聚类时,需要关注以下几个关键点: 1. 数据预处理:包括去除停用词、词干提取、词形还原等,以减少噪声并提高聚类效果。 2. 向量化:将文本转换为数值向量,如BoW或TF-IDF,以便进行距离计算...
在本项目中,我们将深入探讨如何使用PyTorch框架来实现CRAFT(Character Region Awareness For Text Detection)文本检测算法。CRAFT算法因其对字符区域的高度敏感性而得名,它在复杂背景和变形文本检测方面表现出色...