数据结构-串的匹配算法拓展

字符串匹配算法及另外的操作

字符串匹配+统计比较次数

/***字符串匹配算法***/
#include<cstring>
#include<iostream>
using namespace std;

#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status;
#define MAXSTRLEN 255           //用户可在255以内定义最长串长
typedef struct {        //0号单元存放串的长度
 char ch[MAXSTRLEN+1];
 int length;
  }SString;
Status StrAssign(SString &T, char *chars) { //生成一个其值等于chars的串T
    int i;
    if (strlen(chars) > MAXSTRLEN)
        return ERROR;
    else {
        T.length = strlen(chars);
        for (i = 1; i <= T.length; i++)
            T.ch[i] = *(chars + i - 1);
        return OK;
    }
}

//填写4.1 BF算法 并增加计算比较次数
int Index_BF(SString S, SString T, int pos)
{
    //返回模式T在主串S中第pos个字符之后第s一次出现的位置。若不存在,则返回值为0
    //其中,T非空,1≤pos≤StrLength(S)
    int i=pos; int j=1;
    int count1=0;
    while(i<=S.length&&j<=T.length){
        count1++;
//      cout<<"比较次数为:"<<count1<<endl;
        if(S.ch[i]==T.ch[j]){
            ++i;++j;
        }else{
            i=i-j+2;j=1;
        }

    }
    cout<<"比较次数为:"<<count1<<endl;
    if(j>T.length)
            return i-T.length;
        else return 0;

}//Index
//算法4.3 计算next函数值
void get_next(SString T, int next[])
{ //求模式串T的next函数值并存入数组next
    int i = 1, j = 0;
    next[1] = 0;
    while (i < T.length)
        if (j == 0 || T.ch[i] == T.ch[j])
        {
            ++i;
            ++j;
            next[i] = j;
        }
        else
            j = next[j];
}//get_next

//算法4.2 KMP算法,增加计算比较次数
int Index_KMP(SString S, SString T, int pos, int next[])
{   // 利用模式串T的next函数求T在主串S中第pos个字符之后的位置的KMP算法
    //其中,T非空,1≤pos≤StrLength(S)
    int i = pos, j = 1;
    int count2=0;
    while (i <= S.length && j <= T.length)
    {
        count2++;
        //cout<<"比较次数为:"<<count2<<endl;
    if (j == 0 || S.ch[i] == T.ch[j]) // 继续比较后继字
        {
            ++i;
            ++j;
        }
        else
            j = next[j]; }// 模式串向右移动
    cout<<"比较次数为:"<<count2<<endl;
    if (j > T.length) // 匹配成功
        return i - T.length;
    else
        return 0;

}//Index_KMP
int main()
{
    SString S;
    StrAssign(S,"bbabababababba") ;
    SString T;
    StrAssign(T,"babb") ;

    cout<<"调用BF算法:"<<endl;
    cout<<"主串和子串在第"<<Index_BF(S,T,1)<<"个字符处首次匹配\n";
    int *p = new int[T.length+1]; // 生成T的next数组
    get_next(T,p);
    cout<<"调用KMP算法:"<<endl;
    cout<<"主串和子串在第"<<Index_KMP(S,T,1,p)<<"个字符处首次匹配\n";
    return 0;
}

统计匹配字符串+统计子串出现次数

/***字符串匹配算法***/
#include<cstring>
#include<iostream>
using namespace std;

#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status;
#define MAXSTRLEN 255           //用户可在255以内定义最长串长
typedef struct {        //0号单元存放串的长度
 char ch[MAXSTRLEN+1];
 int length;
  }SString;
Status StrAssign(SString &T, char *chars) { //生成一个其值等于chars的串T
    int i;
    if (strlen(chars) > MAXSTRLEN)
        return ERROR;
    else {
        T.length = strlen(chars);
        for (i = 1; i <= T.length; i++)
            T.ch[i] = *(chars + i - 1);
        return OK;
    }
}

//填写4.1 BF算法 并增加计算比较次数
int Count_BF(SString S, SString T, int pos)
{
    //返回模式T在主串S中第pos个字符之后第s一次出现的位置。若不存在,则返回值为0
    //其中,T非空,1≤pos≤StrLength(S)
    int count=0;
    int i=pos;
    int j=1;
    for(i=pos;i<=S.length;){
        //cout<<i;
    while(i<=S.length&&j<=T.length){

        if(S.ch[i]==T.ch[j]){
            ++i;++j;
        }else{
            i=i-j+2;j=1;
        }

    }
    if(j>T.length){
        pos = i-T.length;
        i=i-j+2;
        j=1;
//      cout<<pos<<"&"<<i<<endl;
        count++;
        continue;
    }
}
    return count;

}//Index
//算法4.3 计算next函数值
void get_next(SString T, int next[])
{ //求模式串T的next函数值并存入数组next
    int i = 1, j = 0;
    next[1] = 0;
    while (i < T.length)
        if (j == 0 || T.ch[i] == T.ch[j])
        {
            ++i;
            ++j;
            next[i] = j;
        }
        else
            j = next[j];
}//get_next

//算法4.2 KMP算法,增加计算比较次数
int Index_KMP(SString S, SString T, int pos, int next[])
{   // 利用模式串T的next函数求T在主串S中第pos个字符之后的位置的KMP算法
    //其中,T非空,1≤pos≤StrLength(S)
    int i = pos, j = 1,count=0;
    for(i=pos;i<=S.length;){
        while (i <= S.length && j <= T.length)
    {
    if (j == 0 || S.ch[i] == T.ch[j]) // 继续比较后继字
        {
            ++i;
            ++j;
        }
        else
            j = next[j]; }// 模式串向右移动

    if (j > T.length) // 匹配成功
        pos = i - T.length;
        i=i+1;
        j=1;
        count++;
    }

    return count;   

}//Index_KMP
int main()
{
    SString S;
    StrAssign(S,"bbababbbababababbababb");
            //bba babb bababa babb a babb 3次
    SString T;
    StrAssign(T,"babb") ;

    cout<<"调用BF算法:"<<endl;
    cout<<"子串在主串中出现"<<Count_BF(S,T,1)<<"次\n";
    int *p = new int[T.length+1]; // 生成T的next数组
    get_next(T,p);
    cout<<"调用KMP算法:"<<endl;
    cout<<"子串在主串中出现"<<Index_KMP(S,T,1,p)<<"次\n";
    return 0;
}

原文地址:https://www.cnblogs.com/ygjzs/p/11789299.html

时间: 2024-10-14 12:55:50

数据结构-串的匹配算法拓展的相关文章

数据结构--KMP模式匹配算法

今天,在看数据结构--串这一章节时,看到了KMP算法,相对较复杂些,在此单独做下整理. kmp算法是一种改进的字符串匹配算法,由D.E.Knuth与V.R.Pratt和J.H.Morris同时发现,因此人们称它为克努特--莫里斯--普拉特操作(简称KMP算法).KMP算法的关键是根据给定的模式串W1,m,定义一个next函数.next函数包含了模式串本身局部匹配的信息. 例子: 假如我们要比较两个字符串是否相等. 在T串中查找S串.我们用最笨的方法去想,就是将T串与S串中的每一个元素一一去匹配,

数据结构——串的相关算法实现

数据结构--串的相关算法实现 顺序串的插入函数实现 在进行顺序串的插入时,插入pos将串分为两个部分(假设为A.B,长度为LA.LB)及待插入部分(假设为C,长度为LC),则串由插入前的AB变为ACB,由于是顺序串,插入会引起元素的移动.可能会出现以下的三种情况: ①插入后串长度(LA+LC+LB)<=MAXLEN,则将B后移LC个元素位置,再将C插入: ②插入后串长度 >=MAXLEN 且 pos+LC <=MAXLEN,则 B 后移时会有部分字符被舍弃; ③插入后串长度>MAX

串的匹配算法--C语言实现

串这种数据结构,使用是比较多的,但是它的一些方法在更高级的语言中,比如Java,Python中封装的比较完整了.在这里,我只写了串中使用最多的匹配算法,即串的定位操作.串的匹配算法常用的两种就是朴素匹配算法和KMP匹配算法.代码亲测,可直接执行. 1 #include<stdio.h> 2 3 /*字符串长度*/ 4 int StringLength(char *L) 5 { 6 int i = 0; //记录位置 7 int count = 0; //计数器,记录长度 8 while(L[i

javascript实现数据结构: 串的块链存储表示

和线性表的链式存储结构相类似,也可采用链式方式存储串值.由于串结构的特殊性--结构中的每个数据元素是一个字符,则用链表存储串值时,存在一个"结点大小"的问题,即每个结点可以存放一个字符,也可以存放多个字符. 下面是结点大小为4(即每个结点存放4个字符)的链表: head --> (a) --> (b) --> (c) --> ... --> (i) 当结点大小大于1时,由于串长不一定是结点大小的整倍数,则链表中的最后一个结点不一定全被串值占满,此时通常补上

数据结构—串的堆分配

#include<stdio.h> #include<stdlib.h> typedef struct { char *ch; int length; }HString; void StrAssign(HString &T,char *chars); void StrLength(HString S); void StrCompare(HString S,HString T); void ClearString(HString &S); void Concat(HS

Java数据结构-串及其应用-KMP模式匹配算法

串(string)是由零个或多个宇符组成的有限序列,又名叫字符串. 定义的解释: ??串中的字符数目n称为串的长度,定义中谈到"有限"是指长度n是一个有限的数值. ??零个字符的串称为空串(null string),它的长度为零,可以直接用两双引号一表示,也可以用希腊Φ字母来表示. ??所谓的序列,说明串的相邻字符之间具有前驱和后继的关系. 下面是串的一些概念性东西: ??空格串,是只包含空格的串.注意它与空串的区别,空格串是有内容有长度的,而且可以不止一个空格. ??子串与主串,串中

数据结构——串的朴素模式和KMP匹配算法

一.朴素模式 假设我们要从主串S="goodgoogle"中找到子串T="google"的位置,步骤如下: i表示主串的当前位置下标,j表示子串的当前位置下标,如上图在第一轮比较(i=1开始)中j=4和i=4的位置不匹配,接下来就要指针回退,从i=2开始比较,如下: 如此反复直到比较到 i =(主串长度-子串长度+1)的位置或者 j = 子串的长度 就退出比较循环,上面的主串和子串在比较到i=5的位置就完全匹配了. #include <stdio.h>

数据结构- 串的模式匹配算法:BF和 KMP算法

Brute-Force算法的思想 1.BF(Brute-Force)算法 Brute-Force算法的基本思想是: 1) 从目标串s 的第一个字符起和模式串t的第一个字符进行比较,若相等,则继续逐个比较后续字符,否则从串s 的第二个字符起再重新和串t进行比较. 2) 依此类推,直至串t 中的每个字符依次和串s的一个连续的字符序列相等,则称模式匹配成功,此时串t的第一个字符在串s 中的位置就是t 在s中的位置,否则模式匹配不成功. Brute-Force算法的实现 c语言实现: [cpp] vie

数据结构-串操作应用之词索引表

为书库创建查询索引表 建立词索引表基本步骤: 1.从书目文件中读入一个书目单. 2.从书目单中提取所有关键字插入词表. 3.对词表中的每一个关键字在索引表中进行查找并作相应的插入操作. 详细操作: 1.为识别从书名串中分离出来的单词是否是关键字,需要一张常用词表.顺序扫描书目单,首先分离单词,然后查找常用词表,若不和表中任一词相等,则为关键字,插入临时存放关键字的词表中. 2.在索引表中查询关键字时可能出现两种情况:其中一种是索引表上已经有此关键词的索引项,只要在该项中插入书号索引即可:其二是需