[Java代码] 算法练习08:Sunday算法


  1. package com.kay.cn;
  2. http://www.nvzi91.cn/niaodaoyan/29938.html
  3. import java.util.HashMap;
  4. import java.util.LinkedList;
  5. import java.util.List;
  6. import java.util.Map;
  7. import java.util.Scanner;
  8. http://www.nvzi91.cn/yindaoyan/29939.html
  9. /**http://www.nvzi91.cn/yindaoyan/29940.html
  10. * 在字符串查找算法中,最著名的两个是KMP算法(Knuth-Morris-Pratt)和BM算法(Boyer-Moore).
  11. * 两个算法在最坏情况下均具有线性的查找时间。但在使用上,KMP算法并不比最简单的自带库快多少,而BM算法则往往比KMP
  12. * 算法快很多,但BM算法还不是最快的,Sunday算法是比BM算法更快的一种算法。
  13. *http://www.nvzi91.cn/luanchaonanzhong/29941.html
  14. * Sunday算法的思想和BM算法中的坏字符思想非常类似。差别只是在于Sunday算法在匹配失败之后,是取目标串中当前和
  15. * Pattern字符串对应的部分后面一个位置的字符来做坏字符匹配。当发现匹配失败的时候就判断母串中当前偏移量+Pattern
  16. * 字符串长度 (假设为K位置)的字符在Pattern字符串中是否存在。如果存在,则将该位置和Pattern字符串中的该字符对齐,
  17. * 再从头开始匹配;如果不存在,就将Pattern字符串向后移动,和母串k处的字符对齐,再进行匹配。重复上面的操作直到找到,
  18. * 或母串被找完结束。
  19. *http://www.nvzi91.cn/zigongjiliu/29942.html
  20. * @author kay
  21. * @since 1.0
  22. */
  23. public class SundayTest {
  24. http://www.kmrlyy.com/fujianyan/33454.html
  25. private String text;
  26. private String pattern;
  27. private int currentPos = 0;
  28. // 匹配后的子串第一个字符位置列表
  29. private List<Integer> matchedPosList = new LinkedList<Integer>();
  30. // 匹配字符的Map,记录改匹配字符串有哪些char并且每个char最后出现的位移
  31. private Map<Character, Integer> map = new HashMap<Character, Integer>();
  32. http://www.kmrlyy.com/fujianyan/33455.html
  33. @SuppressWarnings("resource")
  34. @org.junit.Test
  35. public void Test() {
  36. Scanner scan = new Scanner(System.in);
  37. System.out.println("请输入文本:");
  38. text = scan.nextLine();
  39. System.out.println("请输入模型:");
  40. pattern = scan.nextLine();
  41. http://www.kmrlyy.com/gongjingmilan/33456.html
  42. if (pattern.length() == 1) {
  43. System.out.println("模型字符长度不能为1!");
  44. }
  45. else if ("".equals(pattern)) {
  46. System.out.println("模型不能为空!");
  47. }http://www.kmrlyy.com/penqiangyan/33457.html
  48. else {
  49. List<Integer> distance = sundaySeach();
  50. System.out.println("文本 " + text + " 和" + "模型" + pattern + " 的编辑距离为:" + distance);
  51. }
  52. }
  53. http://www.kmrlyy.com/niaodaoyan/33458.html
  54. /**
  55. * Sunday 算法具体执行情况
  56. * @return List<Integer> Sunday匹配的结果集
  57. */
  58. private List<Integer> sundaySeach() {
  59. // Sunday匹配时,用来存储Pattern中每个字符最后一次出现的位置,从左到右的顺序 初始化map
  60. for (int i = 0; i < pattern.length(); i++) {
  61. this.map.put(pattern.charAt(i), i);
  62. }
  63. return sundayMatch();
  64. }
  65. http://m.nvzi91.cn/penqiangyan/29351.html
  66. /**
  67. * Sunday匹配,假定Text中的字符的位置为:当前偏移量+Pattern字符串长度+1
  68. * @return List<Integer> 返回文本和模型类比的结果集
  69. */
  70. private List<Integer> sundayMatch() {
  71. if (!matchFromSpecialPos(currentPos)) {
  72. // 如果Text中的字符没有在Pattern字符串中出现,则跳过整个Pattern字符串长度
  73. if ((currentPos + pattern.length() + 1) < text.length()
  74. && !map.containsKey(text.charAt(currentPos + pattern.length() + 1))) {
  75. currentPos += pattern.length();
  76. }
  77. else {
  78. // 如果Text中的字符在Pattern字符串中出现,则将Text中的字符的位置和Pattern字符串中的最后一次出现的字符的位置对齐
  79. if ((currentPos + pattern.length() + 1) > text.length()) {
  80. currentPos += 1;
  81. }
  82. else {
  83. currentPos += pattern.length() - (Integer) map.get(text.charAt(currentPos + pattern.length()));
  84. }http://m.nvzi91.cn/zigongai/29352.html
  85. }
  86. // 匹配完成,返回全部匹配成功的初始位移
  87. if ((text.length() - currentPos) < pattern.length()) {
  88. return matchedPosList;
  89. }
  90. http://m.nvzi91.cn/jiankang/29353.html
  91. sundayMatch();
  92. }
  93. else {
  94. // 匹配成功前进一位然后再次匹配
  95. matchedPosList.add(currentPos);
  96. currentPos += 1;
  97. sundayMatch();
  98. }
  99. return matchedPosList;
  100. }
  101. /**
  102. * 检查从Text的指定偏移量开始的子串是否和Pattern匹配
  103. * @param pos text的指定偏移量
  104. * @return boolean 否和Pattern匹配
  105. */
  106. private boolean matchFromSpecialPos(int pos) {
  107. if ((text.length() - pos) < pattern.length()) {
  108. return false;
  109. }
  110. www.nvzi91.cn
  111. for (int i = 0; i < pattern.length(); i++) {
  112. if (text.charAt(pos + i) == pattern.charAt(i)) {
  113. if (i == (pattern.length() - 1)) {
  114. return true;
  115. }
  116. continue;
  117. }www.kmrlyy.com
  118. else {
  119. break;
  120. }
  121. }
  122. m.nvzi91.cn
  123. return false;
  124. }
  125. }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值