[转帖]字符匹配算法(KMP)_Android, Python及开发编程讨论区_Weblogic技术|Tuxedo技术|中间件技术|Oracle论坛|JAVA论坛|Linux/Unix技术|hadoop论坛_联动北方技术论坛  
网站首页 | 关于我们 | 服务中心 | 经验交流 | 公司荣誉 | 成功案例 | 合作伙伴 | 联系我们 |
联动北方-国内领先的云技术服务提供商
»  游客             当前位置:  论坛首页 »  自由讨论区 »  Android, Python及开发编程讨论区 »
总帖数
1
每页帖数
101/1页1
返回列表
0
发起投票  发起投票 发新帖子
查看: 3750 | 回复: 0   主题: [转帖]字符匹配算法(KMP)        下一篇 
fozhyn
注册用户
等级:上士
经验:317
发帖:101
精华:0
注册:2011-10-18
状态:离线
发送短消息息给fozhyn 加好友    发送短消息息给fozhyn 发消息
发表于: IP:您无权察看 2011-10-19 15:19:37 | [全部帖] [楼主帖] 楼主

Java代码   北京联动北方科技有限公司


package sunfa.kmp;
public class SimpleKMP {
      public static void main(String[] args) {
            int index = simpleKmp("12444abababab", "444ababab");
            System.out.println(index);
      }
      private static int simpleKmp(String src, String dect) {
            if (dect.length() > src.length())
            return -1;
            char[] srcArr = src.toCharArray();
            char[] dectArr = dect.toCharArray();
            for (int i = 0; i < srcArr.length; i++)
            if ((i + dect.length()) <= srcArr.length
            && comp(srcArr, dectArr, i, i + dect.length()))
            return i;
            return -1;
      }
      private static boolean comp(char[] srcArr, char[] dectArr, int a0, int a1) {
            int j = 0;
            for (int i = a0; i < a1; i++)
            if (srcArr[i] != dectArr[j++])
            return false;
            return true;
      }
}


Java代码   北京联动北方科技有限公司


package sunfa.kmp;
import java.util.Arrays;
/**


 * 这个算法比较靠谱,而且看的懂 KMP算法分2步: 

 * <p>


 * ①根据子字符串得到next数组 

 * <p>


 * ②子串与主串进行朴素比较,但是匹配不上的时候就查找next数组。 
 * 以前在这个时候是i回溯并且j=0,kmp算法是i不动并且j回溯(根据next数组进行回缩, 
 * 找到那个能够匹配上的地方。它怎么知道哪个地方能够匹配的上呢,看看next数组的实现就清楚了。) 

 *


 * next数组的实现:对子串进行迭代,每次取p.substring(0, i)个字符,然后把该字符劈成两半并且比较左半边和右半边是否相等, 
 * 如果相等则将两半处的索引n加到next数组中去 

 * <p>
*
*
*
public class KMP {
      String s; // 主字符串  
      String p; // 匹配字符串  
      int[] next; // 匹配字符串的next数组  
      int times; // 记录匹配的次数  
      int index; // 记录查找到的位置  
      KMP(String s, String p) {
            this.s = s;
            this.p = p;
            this.next = new int[p.length()];
            for (int i = 0; i < p.length(); i++) {
                  if (i == 0) {
                        this.next[i] = -1;
                  } else if (i == 1) {
                        this.next[i] = 0;
                  } else {
                  // 对某个位置之前的字符串考察其开始部分和结尾部分是否相同  
                  this.next[i] = next(p.substring(0, i));
            }
      }
      this.times = 0;
      this.index = -1;
}
private int next(String p) {
      int length = p.length() / 2;
      while (length > 0) {
            if (p.substring(0, length).compareTo(
            p.substring((p.length() - length), p.length())) == 0) {
                  System.out.println(p + "<" + p.substring(0, length) + "="
                  + p.substring((p.length() - length), p.length()));
                  return length;
            }
            length--;
      }
      return length;
}
boolean match() {
int i = 0;// 主串索引  
int j = 0;// 子串索引  
int index = -1; // index记录匹配的位置  
while (i < this.s.length() && j < this.p.length()) {
      if (this.s.charAt(i) == this.p.charAt(j)) {// 1、按照朴素模式进行匹配  
            if (j == 0) {
                  index = i;
            }
            i++;
            j++;
      } else {
      // 一直寻找next,直到和当前元素不相等的元素,将其下标赋值给j  
      int newj = this.next[j];// 2、当匹配不上了的时候i不用回溯,只需要根据j的索引去查找next数组  
      System.out.print("debug[");
      while ((newj != -1)
      && (this.p.charAt(newj) == this.p.charAt(j))) {
            // newj回溯  
            newj = this.next[newj];
            System.out.print("newj:" + newj + ",i:" + i + ",j:" + j
            + ",v:" + this.p.charAt(j) + ",next:"
            + Arrays.toString(next) + ",p:" + p);
      }
      System.out.println("]");
      j = newj;
      if (j == -1) {
            i++;// 主串索引++  
            j = 0;// 子串索引重置  
      } else {
      index = i - j;
}
}
this.times++;
}
if (j == this.p.length()) {
      this.index = index;
      return true;
} else {
return false;
}
}
public static void main(String[] args) {
      String s = "1ababcababd1ababcababc_def";
      String p = "ababcababc";
      KMP m = new KMP(s, p);
      // 顺便打印next数组;  
      for (int i = 0; i < m.next.length; i++) {
            System.out.print(m.next[i] + ",");
      }
      System.out.println();
      if (m.match()) {
            System.out.println("match");
            System.out.println("match times: " + m.times);
            int index = m.index;
            System.out.println(index);
      } else {
      System.out.println("not match");
}
}
}




赞(0)    操作        顶端 
总帖数
1
每页帖数
101/1页1
返回列表
发新帖子
请输入验证码: 点击刷新验证码
您需要登录后才可以回帖 登录 | 注册
技术讨论