实验室项目中遇到这样一个需求,将OCR识别后的两段文字进行互相校验并标记出差异。两段文字分别来自不同源的OCR识别,自然会存在差异,而且本身也有误差。实际上这个标记是十分麻烦的,不同于普通的字符串算法,它是一种更加模糊,而且多变但又有着特殊形式的字符串。之前考虑过匹配算法如KMP、自动机之类都不适合;考虑相似度检测的算法如编辑距离和余弦相似度也不适合,实际上不需要这么复杂,只需要根据特殊的规律去标记即可。
在识别出的两段字符串当中,由于是对同一张图片进行的文字识别,因此绝大部分的字符串都是相同,存在的不同主要是识别误差,可能是漏了、多了或者错了。源图片是电子病历,所以会存在许多的不同字符,这是很麻烦的事情。
由于比较的字符串很容易多了许多奇奇怪怪符号的干扰,因为符号本身就容易不清晰,出现误差几率更大,并且符号相对内容而言并不重要,所以将两段字符串的符号用正则表达式清除。
//比较时去除不重要的标点符号干扰 String tempA = a.replaceAll("\s*\p{Punct}\s*","");String tempB = b.replaceAll("\s*\p{Punct}\s*","");if(tempA.equalsIgnoreCase(tempB)){Log.e("比较","两者相等");}else{Log.e("比较","两者不等");//标记算法List<String> list = insertMark(tempA,tempB,a,b);//标记结果更新bRs.set((0));tRs.set((1));}
算法思路:
遍历预处理后的两段字符串并比较(不区分大小写),相等就两者下标向前进,每遍历一个字符各自记录出现的次数,利用map集合记录,以字符本身为key,出现的次数为value
如果字符不相等,需要记录当前字符在原始字符串中的下标,为了求得这个坐标,我们前面才要记录各自出现的次数,然后通过key取得最新记录的次数,即表示当前字符在原始字符中出现的次数k,因为它必定不是被预处理掉的字符,接着利用indexOf求出该字符在原始字符串中首次出现的位置,根据记录的次数跳过k-1次,最后一次的索引便是所求的索引
接下来需要定位到有差异的字符到哪里为止,由于绝大部分字符都相同,因此一般情况下,跳过若干位后的字符串必定与第二段字符串相邻索引的字符相同,例子如下:
eg
AB CDE FGH
AB MLKE FGH
此处,当我们定位到第一个不同的是C 与 M,计算得到他们对应在原始字符串的下标后存起来,然后就是如何定位到两者相同字符 E的各自下标了,标记他们C~E和M~E的字符串就完成目标了,如何定位到末尾坐标呢?
简陋实现如下:
/*** 字符串差异标记算法* @param tempA 经过预处理清除干扰后的字符串——前面一段* @param tempB 经过预处理清除干扰后的字符串——另外一段* @param a 原始字符串前面一段* @param b 原始字符串后面一段* @return 原始字符串处理后的标记结果*/private List<String> insertMark(String tempA,String tempB,String a,String b){//a,b标记次数int mFlag1=0;int mFlag2=0;//存储结果的集合List<String> list = new ArrayList<>();//代替HashMap节约内存,ArrayMap双数组基于二分查找&
本文发布于:2024-01-28 20:56:36,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170644660110227.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |