看打模式串匹配算法及遇到的问题

不严格对照看打模式源于速录金老板在提建议给拖拉机加上看打功能

方法一早就有了,但是却不够严谨,所以一直没有下手去做,但后来发现,不做不行,不严谨也要先把功能先做出来。

什么是不严格对照?

在以往的跟打器中,我们都是以一种严格对照的方式来进行判断跟打成绩的,比如说:

原文:跟打器是提升打字速度的工具,我们应该充分的去使用它。
跟打:跟打器和三提升打字速度的,我们应该充分了去使用他。

上面一段原文,一段跟打,在以往的跟打模式中,一般在第四个字 “和” 就已经开始提示错误显红,如果在这个时候,你只是打错字,那么他只会显示一个红色,但是在后面紧跟着多出来的一个字 “三” 这就会使你后面一一对照的文字全部判断为错,下面是我用极速跟打器来显示这一效果。

极速跟打器示范

1

删去多余的 “三” 字后。

删去多余的三后

1 (2)

所以我们就需要一个算法,能让跟打器判断,你这个字是错对照错误的,还是多余的字,或者是漏掉的字。而不是像这样一一对照。如果能从根本上解决这一问题,我们看打练习会更加顺利。

算法思路

这里不使用上面的“原文”和“跟打”例子

第一层循环,给“跟打”一个下标i,从头部开始下标递增,直到“跟打”被遍历完全。 第二层循环,给“跟打”一个下标j,从最尾处开始下标递减的遍历,并用java方法

(注意,两个下标都是标给“跟打”)

原文.indexOf(跟打.substring(i,j)) 在“原文”中,开始匹配“跟打”,找不到则往前缩小跟打的长度,直到找到或着找不到但j递减到等于i为止。就递增i进入下一次循环。

第一次循环匹配

1

黑色为“原文”,红色为“跟打”,当在第一次循环逐渐缩短长度的过程中如果匹配到了,就将两者的下标加上匹配长度(j-i)记下。记为tempbefore和temp1before,假设第一次循环在下标0找到一个长度为5的串,记tempbefore与tempbefore都为5,并将i跳到temp1before上,下次匹配将从“原文”的tempbefore下标开始。

那么j继续回塑到“跟打”的最尾部,i到位置5,假设在第二个循环中,遍历了整个长度都没有找到匹配。那么将i递增,进入第三个循环。

第三个循环中,temp1before必定会比i要小,而这个时候如果匹配成功到一个长度为3的串的且匹配位置在“原文”的5的话。 那么用i-temp1before->6-5=1,就能得知“打字”中多出了一个字。 第三次循环中匹配成功 temp1before变为6+3=9,tempbefore还为5+3=8

第三次循环

1 (2)

第四个循环中,在匹配的字符并不是在tempbefore的8上,而是落在了9 所以我们也能用9-8得知,我们少打了一个字。 此时共同跳到13。

第四次循环

上面是描述了算法在单一情况下的行径,下面来说混合时的计算。

在第五个循环中, 按相对相对偏移分为三种可能。 第一种为相同偏移,第二种为“原文”偏移较大,第三种“跟打”偏移较大,见下图。

相对偏移相同

1

原文偏移较大

2

跟打偏移较大

3

第一种很简单,这个时候直接判断为15-13=2,两个错字就可以解决。 第二种和第三种,只需要计算以下公式计算出错误字数mistemp

mistaketmp=
Math.abs(temp-tempbefore)<Math.abs(temp1-temp1before)
?Math.abs(temp-tempbefore):Math.abs(temp1-temp1before);

######temp为“原文”偏移后位置,temp1为“跟打”偏移后位置 即第二种情况为,(15-13)<(16-13)?(15-13)<(16-13),得出结果是2个错字 第三种情况也一样。 计算出错字后 漏打字数=原文偏移-错字 多打字数=跟打偏移-错字 即 第二种情况:漏打字数=2-2=0,多打字数=3-2=1 第三种情况:漏打字数=3-2=1,多打字数=2-2=0 ####算法缺陷 稍微更改一下上面的例子 ######原文:跟打器是提升打字速度的工具,我们应该充分的去使用它。 ######跟打:跟打器的三提升打字速度的,我们应该充分了去使用他。 将“跟打”中的“和”字换成“的”字, 到这里,第一次循环不用思考都可以知道,原文和跟打都会匹配到“跟打器”并将下标标到3 让我们来看看第二次循环,他在第二次循环的最后一步时,会匹配到后面的“的”字。这样一来。按照上面的逻辑,在这个循环中程序判断会将“提升打字速度”判断为漏字。

第二次循环

1 而当我们进入第三次循环时会发现什么? 你会发现,“跟打”中的“三”提升打字速”变成了多打字,“工具”对照“度的”变成了错字。 后面框住部分才会变成正常匹配。

第三次循环

2 就在这缺陷下,我无法解决这个问题。所以我后来思考将长文章按逗号拆分,以减少连带效应,使这个错误影响范围尽量减少,但也带来了一个新的问题:

如果“原文”与“跟打”中的逗号数量不一致,会导致更大的错误,导致一整句话的丢失。轻则丢失最后一句话,重则将整篇文章错位。

算法demo

# 跟打器 

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×