zoukankan      html  css  js  c++  java
  • [小明学算法]7.字符串匹配算法---BM

    1.简介

      BM算法是比较优秀的字符串匹配算法.

    2.主要思想介绍

      BM算法主要有三个要点
        ①.从pattern的后面往前比较
        ②.对匹配过的数据应用KMP
        ③.将pattern向右滑,找到与string当前字符匹配的a相同的字符位置(若不存在,直接滑过sizeof(length))
        (第三步目前只实现了滑过在右侧以匹配过字符不存在的情况)

    3.代码

      1 #include <iostream>
      2 using namespace std;
      3 bool isSub(char* A, char* B, int lengthA, int lengthB);
      4 void Print(int* table, int length);
      5 //记录字符在pattern中的最后位置
      6 int* PreBMLocation(char* pattern, int length)
      7 {
      8     //字符的最大值为256
      9     int* location = new int[256];
     10     for (int i = 0; i < 256; i++)
     11         location[i] = length;
     12     for (int i = 0; i < length; i++)
     13         location[pattern[i]] = length-i-1;
     14 
     15     return location;
     16 }
     17 
     18 //和KMP一样的从后往前比对思路
     19 void PreBMTable(char* pattern, int *Table, int length)
     20 {
     21     //设定哨兵
     22     Table[length] = 1;
     23     //为每一个pattern[i]计算可偏移值(即之前有多少重复)
     24     for (int i = length - 1; i >= 0; i--)
     25     {
     26         Table[i] = Table[i + 1];
     27         //计算从新加入的重复
     28         for (int j = length - Table[i]; j >= i; j--)
     29         {
     30 
     31             //从i到j是否是已经匹配过的子串
     32             if (isSub(pattern, pattern + i, length, j - i))
     33             {
     34                 //如果存在一个字串,结束
     35                 break;
     36             }
     37             else
     38             {
     39                 //如果不存在重复部分,移动量加一
     40                 Table[i]++;
     41             }
     42         }
     43     }
     44 }
     45 
     46 //B是否是A的尾子串(从末尾一位开始比较)
     47 bool isSub(char* A, char* B, int lengthA, int lengthB)
     48 {
     49     int start = lengthA - lengthB;
     50     for (int i = lengthB - 1; i >= 0; i--)
     51     {
     52         if (A[start + i] != B[i])
     53             return false;
     54     }
     55 
     56     return true;
     57 }
     58 
     59 void Print(int* table, int length)
     60 {
     61     for (int i = 0; i < length; i++)
     62     {
     63         cout << table[i] << " ";
     64     }
     65     cout << endl;
     66 }
     67 int Max(int a, int b)
     68 {
     69     return a>b ? a : b;
     70 }
     71 
     72 void BM(char* string, int m, char* pattern, int n)
     73 {
     74     //BM算法主要有三个要点
     75     //1.从pattern的后面往前比较
     76     //2.对匹配过的数据应用KMP
     77     //3.将pattern向右滑,找到与string当前字符匹配的a相同的字符位置(若不存在,直接滑过sizeof(length))
     78     //(第三步目前只实现了滑过在右侧以匹配过字符不存在的情况)
     79 
     80     //先处理pattern
     81     int* table = new int[n + 1];
     82     PreBMTable(pattern, table, n);
     83     int* loacation = PreBMLocation(pattern, n);
     84 
     85     for (int i = 0; i < m; )
     86     {
     87         for (int j = n - 1; j >= 0; j--)
     88         {
     89             char a = string[i+j];
     90             char b = pattern[j];
     91 
     92             if (a != b)
     93             {
     94                 //这个是记录了string中当前比较字符在pattern中的位置,并计算移动和其匹配所做的移动数(可能为负)
     95                 //当不存在时,直接滑过.
     96                 int t = loacation[a]-(n - 1-j)  ;
     97                 i += Max(table[j],t ); 
     98                 //cout << t <<" t1:"<<t1 <<"a:"<<a<<endl;
     99                 break;
    100             }
    101 
    102             if (j == 0)
    103             {
    104                 //第一次匹配起点在string中的位置
    105                 cout << i << endl;
    106                 return;
    107             }
    108         }
    109     }
    110 
    111     
    112 }
    113 
    114 void main()
    115 {
    116     char string[] = "bcrcaaaaabbbbcd";
    117     char pattern[] = "aaaabbbbcd";
    118     int length = sizeof(pattern);
    119     int* table = new int[length];
    120 
    121     BM(string, sizeof(string)-1, pattern, length - 1);
    122 
    123 
    124     int a;
    125     cin >> a;
    126 }
    View Code
  • 相关阅读:
    Charpter5 软件测试总结
    Charpter3 关于闰年测试
    Charpter2 新的测试用例
    Charpter1 等价类划分方法分析与应用
    软件测试第一周学习总结
    关于软件测试学习的心得
    软件测试-同行评审
    白盒测试
    黑盒测试
    Java实现的闰年测试程序
  • 原文地址:https://www.cnblogs.com/WongSiuming/p/5130561.html
Copyright © 2011-2022 走看看