字符串模糊匹配使用递归实现

来源:互联网 发布:苹果mac系统如何更新 编辑:程序博客网 时间:2024/05/21 10:34

字符串一个字不对就匹配不上一直困扰着我们,

使用递归方法实现字符串模糊顺序匹配。

例如:

字符串1:神啊,救救我吧

字符串2:神啊救救我吧

这2个字符串能匹配6个,最大字符串长度7,那么就是6/7=0.857 如果设定匹配率为75%那么这2个字符串就是匹配。

这2个字符串有一个不匹配,如果我们设定可以容忍2个字符错误,那么这2个字符串也是匹配的。

如果实现模糊匹配呢?

分析:

字符串比较2种情况,一种是匹配上,一种没匹配上。匹配上有1种处理方法。没匹配上有3种处理方法。

匹配上:字符串都下移(1相当于光标)

神啊,救救我吧

1

1

神啊救救我吧

 

神啊,救救我吧

    1

    1

神啊救救我吧

没匹配上:字符串1不变,2下移;字符串1下移,2不变;字符串1,2都下移
字符串1不变,2下移;

救救我吧

1

1

神啊救救我吧

救救我吧

1

  1

神啊救救我吧

字符串1下移,2不变;

,救救我吧

1

1

救救我吧

,救救我吧

    1

1

救救我吧
字符串1,2都下移;
,救救我吧

1

1

啊救救我吧

,救救我吧

   1

   1

啊救救我吧

计算这3种匹配的数。取出最大值。

下面实现代码:

 

interface MatchHander{boolean compare(int a,int b);}public class Match {/**  * 百分之多少之内匹配错误可以接受 * a与ab匹配为百分之50的错误率。 * @param percent 设置匹配百分比 * @param src 字符串1 * @param dest 字符串2 * @param hander 匹配规则 * @return */public static boolean match(double percent,String src,String dest,MatchHander hander){char[] csrc = src.toCharArray();char[] cdest = dest.toCharArray();double score = 0;score = cal(csrc,0,cdest,0,hander);int max = csrc.length>cdest.length?csrc.length:cdest.length;System.out.println("最小匹配百分比:"+percent+",成功匹配百分比:"+score / max);return score / max > percent;}/** * 几个错误的字符可以接受 * a与ab为1个字符错误可以接受 * @param percent 设置匹配百分比 * @param src 字符串1 * @param dest 字符串2 * @param hander 匹配规则 * @return */public static boolean match(int errorNum,String src,String dest,MatchHander hander){char[] csrc = src.toCharArray();char[] cdest = dest.toCharArray();int score = 0;score = cal(csrc,0,cdest,0,hander);int max = csrc.length>cdest.length?csrc.length:cdest.length;System.out.println("可以接受错误数:"+errorNum+",发现错误数:"+(max - score) );return max - score  <= errorNum;}/** * 2个字符串75%匹配成功返回true * @param src * @param dest * @return */public static boolean match(double percent,String src,String dest){return match(percent,src,dest,new MatchHander(){@Overridepublic boolean compare(int a, int b) {return a==b;}});}/** * 2个字符串错几个字符可以接受 * @param errorNum * @param src * @param dest * @return */public static boolean match(int errorNum,String src,String dest){return match(errorNum,src,dest,new MatchHander(){@Overridepublic boolean compare(int a, int b) {return a==b;}});}/** * 使用递归方法匹配字符串 * @param csrc * @param i * @param cdest * @param j * @param hander * @return */private static int cal(char[] csrc, int i, char[] cdest, int j, MatchHander hander) {int score = 0;if(i >= csrc.length || j >= cdest.length)return 0;boolean ismatch = hander.compare(csrc[i], cdest[j]);if(ismatch){score++;if(i+1<csrc.length && j+1<cdest.length)score +=  cal(csrc, i+1, cdest, j+1, hander) ;}else{int temp1 = 0;int temp2 = 0;int temp3 = 0;temp1 +=  cal(csrc, i, cdest, j+1, hander) ;temp2 +=  cal(csrc, i+1, cdest, j, hander) ;temp3 +=  cal(csrc, i+1, cdest, j+1, hander) ;int temp4 = Math.max(temp1, temp2);score += Math.max(temp3, temp4);}return score;}public static void main(String[] args) {//三个字符错误可以接受System.out.println(match(3,"神啊,救救我吧","神啊救救我吧"));//75%匹配可以接受System.out.println(match(0.75,"神啊,救救我吧","神啊救救我吧"));}}


 

当然这个效率非常慢。10个字符之内的可以考虑。

此程序字符串


  String a="N55-8P-SSK9=【产品描述:附件|Nexus 5500 存储附件(8端口)】";
  String b="N55-8P-SSK9=【产品描述:配件|Nexus 5500 存储配件(8端口)】";

无法匹配优化后可以匹配。

 优化后代码

 

原创粉丝点击