[Java代码] 算法练习08:Sunday算法
2016-03-15 17:21
585 查看
package com.kay.cn; http://www.nvzi91.cn/niaodaoyan/29938.html import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Scanner; http://www.nvzi91.cn/yindaoyan/29939.html /**http://www.nvzi91.cn/yindaoyan/29940.html * 在字符串查找算法中,最著名的两个是KMP算法(Knuth-Morris-Pratt)和BM算法(Boyer-Moore). * 两个算法在最坏情况下均具有线性的查找时间。但在使用上,KMP算法并不比最简单的自带库快多少,而BM算法则往往比KMP * 算法快很多,但BM算法还不是最快的,Sunday算法是比BM算法更快的一种算法。 *http://www.nvzi91.cn/luanchaonanzhong/29941.html * Sunday算法的思想和BM算法中的坏字符思想非常类似。差别只是在于Sunday算法在匹配失败之后,是取目标串中当前和 * Pattern字符串对应的部分后面一个位置的字符来做坏字符匹配。当发现匹配失败的时候就判断母串中当前偏移量+Pattern * 字符串长度 (假设为K位置)的字符在Pattern字符串中是否存在。如果存在,则将该位置和Pattern字符串中的该字符对齐, * 再从头开始匹配;如果不存在,就将Pattern字符串向后移动,和母串k处的字符对齐,再进行匹配。重复上面的操作直到找到, * 或母串被找完结束。 *http://www.nvzi91.cn/zigongjiliu/29942.html * @author kay * @since 1.0 */ public class SundayTest { http://www.kmrlyy.com/fujianyan/33454.html private String text; private String pattern; private int currentPos = 0; // 匹配后的子串第一个字符位置列表 private List<Integer> matchedPosList = new LinkedList<Integer>(); // 匹配字符的Map,记录改匹配字符串有哪些char并且每个char最后出现的位移 private Map<Character, Integer> map = new HashMap<Character, Integer>(); http://www.kmrlyy.com/fujianyan/33455.html @SuppressWarnings("resource") @org.junit.Test public void Test() { Scanner scan = new Scanner(System.in); System.out.println("请输入文本:"); text = scan.nextLine(); System.out.println("请输入模型:"); pattern = scan.nextLine(); http://www.kmrlyy.com/gongjingmilan/33456.html if (pattern.length() == 1) { System.out.println("模型字符长度不能为1!"); } else if ("".equals(pattern)) { System.out.println("模型不能为空!"); }http://www.kmrlyy.com/penqiangyan/33457.html else { List<Integer> distance = sundaySeach(); System.out.println("文本 " + text + " 和" + "模型" + pattern + " 的编辑距离为:" + distance); } } http://www.kmrlyy.com/niaodaoyan/33458.html /** * Sunday 算法具体执行情况 * @return List<Integer> Sunday匹配的结果集 */ private List<Integer> sundaySeach() { // Sunday匹配时,用来存储Pattern中每个字符最后一次出现的位置,从左到右的顺序 初始化map for (int i = 0; i < pattern.length(); i++) { this.map.put(pattern.charAt(i), i); } return sundayMatch(); } http://m.nvzi91.cn/penqiangyan/29351.html /** * Sunday匹配,假定Text中的字符的位置为:当前偏移量+Pattern字符串长度+1 * @return List<Integer> 返回文本和模型类比的结果集 */ private List<Integer> sundayMatch() { if (!matchFromSpecialPos(currentPos)) { // 如果Text中的字符没有在Pattern字符串中出现,则跳过整个Pattern字符串长度 if ((currentPos + pattern.length() + 1) < text.length() && !map.containsKey(text.charAt(currentPos + pattern.length() + 1))) { currentPos += pattern.length(); } else { // 如果Text中的字符在Pattern字符串中出现,则将Text中的字符的位置和Pattern字符串中的最后一次出现的字符的位置对齐 if ((currentPos + pattern.length() + 1) > text.length()) { currentPos += 1; } else { currentPos += pattern.length() - (Integer) map.get(text.charAt(currentPos + pattern.length())); }http://m.nvzi91.cn/zigongai/29352.html } // 匹配完成,返回全部匹配成功的初始位移 if ((text.length() - currentPos) < pattern.length()) { return matchedPosList; } http://m.nvzi91.cn/jiankang/29353.html sundayMatch(); } else { // 匹配成功前进一位然后再次匹配 matchedPosList.add(currentPos); currentPos += 1; sundayMatch(); } return matchedPosList; } /** * 检查从Text的指定偏移量开始的子串是否和Pattern匹配 * @param pos text的指定偏移量 * @return boolean 否和Pattern匹配 */ private boolean matchFromSpecialPos(int pos) { if ((text.length() - pos) < pattern.length()) { return false; } www.nvzi91.cn for (int i = 0; i < pattern.length(); i++) { if (text.charAt(pos + i) == pattern.charAt(i)) { if (i == (pattern.length() - 1)) { return true; } continue; }www.kmrlyy.com else { break; } } m.nvzi91.cn return false; } } |
相关文章推荐
- 深入理解Java的接口和抽象类
- 基于java web的博客平台(四)
- SpringMVC中使用Interceptor拦截器
- Java数据类型字节数
- SpringMVC拦截器(资源和权限管理)-login拦截
- 基于java web的博客平台(三)
- Java中Date插入数据库的一些问题总结(二)
- Java高级开发反射手段更换对象根节点内容
- Java 从流中读取byte的奇怪现象,出现负值,详解
- 多重json转换为JAVA对象
- 基于java web的博客平台(二)
- 采摘Java初学者博客之Java collection
- JAVA学习章
- Java并发编程:volatile关键字解析
- eclipse 生成javadoc乱码问题解决
- 深入理解Java的接口和抽象类
- JDK动态代理和CGLIB的区别
- Eclipse查找替换巧妙技巧用法
- SpringIoc BeanDefinition载入交互过程
- JNI(Java Native Interface)