【考研-数据结构】串

【考研-数据结构】串

串(大总结)

//串
#include <iostream>
#define MaxSize 20
using namespace std;
typedef struct SString
{
    char ch[MaxSize];
    int length;
}SString;

//求串长
int StrLength(SString S) {
    return S.length;
}

//清空
bool ClearString(SString& S) {
    S.length = 0;  //逻辑上清空
    return true;
}

//比较操作
int StrCompare(SString S, SString T) {
    for (int i = 1; i <= S.length && i <= T.length; i++) {
        if (S.ch[i] != T.ch[i]) return S.ch[i] - T.ch[i];
    }
    //扫描的所有字符都相同,则长度长的串更大
    return S.length - T.length;
}

//求子串(pos为开始的位置,len为要截取子串的长度)
bool SubString(SString& Sub, SString S, int pos, int len) {
    //子串范围越界
    if (pos + len - 1 > S.length) return false;
    for (int i = pos; i < pos + len; i++) {
        Sub.ch[i - pos + 1] = S.ch[i];
    }
    Sub.length = len;
    return true;
}

//定位操作
int Index_01(SString S, SString T) {
    int i = 1;
    int n = StrLength(S);  //主串的长度
    int m = StrLength(T);  //要定位的子串的长度
    SString sub;  //暂时存储子串
    while (i <= n - m + 1) {
        SubString(sub, S, i, m);
        if (StrCompare(sub, T) != 0) i++;
        else return i;
    }
    return 0;  //S中不存在
}


//朴素模式匹配算法
int Index_02(SString S, SString T) {
    int i = 1, j = 1;
    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) {
        return i - T.length;
    }
    else {
        return 0;
    }
    /*另一种,使用k控制子串的移动
    int  k = 1;
    int i = 1;
    int j = 1;
    while(i<=S.length&&j<=T.length){
        if(S.ch[i] == T.ch[j]){
            ++i;
            ++j;
        }else{
            k++;
            i = k;
            j = 1;
        }
    }
    if(j>T.length){
        return k;
    }else{
        return 0;
    }
    */
}

//KMP算法(next数组是需要手算的,next[1]永远=0)
//也可以使用get_next函数将next计算出来,在此函数内部调用
int Index_KMP(SString S, SString T, int next[]) {
    int i = 1, j = 1;
    while (i <= S.length && j <= T.length) {
        if (j == 0 || S.ch[i] == T.ch[j]) {
            j++;
            i++;
        }
        else {
            j = next[j];
        }
    }
    if (j > T.length) {
        return i - T.length;
    }
    else {
        return 0;
    }
}

//计算next数组
void get_next(SString T, int 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];
        }
    }
}
//计算nextval数组(改进版的next)
/*
(简单来说,如果后面的字符与前面的某一个字符相同,就将和这个位置的nextval赋值为0)
先算出next数组,令nextval[1] = 0
for(int j = 2;j<=T.length;j++) {
    if(T.ch[next[j]] == T.ch[j])
        nextval[j] = nextval[next[j]];
    else
        nextval[j] = next[j];
}
*/
void get_nextval(SString T,int nextval[]){
    int i = 1;
    int j = 0;
    while(i<T.length){
        if(j == 0||T.ch[i] == T.ch[j]){
            ++i;
            ++j;
            if(T.ch[i]!=T.ch[j]) nextval[i] = j;
            else nextval[i] = nextval[j];
        }else{
            j = nextval[j];
        }
    }
}

int main() {
    SString S;
    S.length = 4;
    S.ch[1] = 'a';
    S.ch[2] = 'b';
    S.ch[3] = 'c';
    S.ch[4] = 'd';
    SString T;
    T.length = 2;
    T.ch[1] = 'c';
    T.ch[2] = 'd';

    cout << Index_02(S, T) << endl;

    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值