4-1 串——顺序实现(C/C++语言)

4-1 串——顺序实现(C/C++语言)

实现的功能

bool StrAssign(SString& S, char c);                             //赋值操作
void StrCopy(SString& T, SString S);                            //复制串
bool StrEmpty(SString S);                                       //判空
bool Concat(SString& T, SString S1, SString S2);                //串连接
int StrLength(SString S);                                       //求串长 
bool SubString(SString& Sub, SString S, int pos, int len);      //求子串
int StrCompare(SString S, SString T);                           //比较字符串大小
int Index(SString S, SString T);                                //求子串的位置
int Index_Simple(SString S, SString T);                         //朴素模式匹配算法
void get_next(SString T, int next[]);                           //获取next数组
void get_nextval(SString T, int nextval[]);                     //获取nextval数组
int Index_KMP_Next(SString S, SString T);                       //KMP算法使用next数组
int Index_KMP_Nextval(SString S, SString T);                    //KMP算法使用next数组
void CleanString(SString& S);                                   //清空链表
//void DystroyString(SString& S);                               //销毁串 数组形式,系统自动收回
void ShowString(SString S);                                     //输出串

完整代码:

/*
    Name:SString(串的顺序实现)
    Copyright:
    Author: Sdjzu_Nxy
    Date: 2023 年 2 月 28 日
    Description:
*/
#include<stdio.h>
#include<stdlib.h>

#define MaxSize 255

typedef struct {
    char ch[MaxSize];
    int length;
} SString;

bool StrAssign(SString& S, char c);                             //赋值操作
void StrCopy(SString& T, SString S);                            //复制串
bool StrEmpty(SString S);                                       //判空
bool Concat(SString& T, SString S1, SString S2);                //串连接
int StrLength(SString S);                                       //求串长 
bool SubString(SString& Sub, SString S, int pos, int len);      //求子串
int StrCompare(SString S, SString T);                           //比较字符串大小
int Index(SString S, SString T);                                //求子串的位置
int Index_Simple(SString S, SString T);                         //朴素模式匹配算法
void get_next(SString T, int next[]);                           //获取next数组
void get_nextval(SString T, int nextval[]);                     //获取nextval数组
int Index_KMP_Next(SString S, SString T);                       //KMP算法使用next数组
int Index_KMP_Nextval(SString S, SString T);                    //KMP算法使用next数组
void CleanString(SString& S);                                   //清空链表
//void DystroyString(SString& S);                               //销毁串 数组形式,系统自动收回
void ShowString(SString S);                                     //输出串

bool StrAssign(SString& S, char c)
{
    if (S.length == MaxSize) {
        return false;
    }
    S.ch[S.length + 1] = c;
    S.length++;
    return true;
}

void StrCopy(SString& T, SString S)
{
    for (int i = 1; i <= S.length; i++) {
        T.ch[i] = S.ch[i];
    }
    T.length = S.length;
}

bool StrEmpty(SString S)
{
    return S.length == 0;
}

bool Concat(SString& T, SString S1, SString S2)
{   
    if (S1.length + S2.length >= MaxSize) {
        return false;
    }
    StrCopy(T, S1);
    for (int i = 1; i <= S2.length; i++)
    {
        StrAssign(T, S2.ch[i]);
    }
    return true;
}

int StrLength(SString S)
{
    return S.length;
}

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 StrCompare(SString S, SString T)
{
    for (int i = 0; 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;
}

int Index(SString S, SString T)
{
    int i = 1, n = StrLength(S), 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;
}

int Index_Simple(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;
    }
}

int Index_KMP_Next(SString S, SString T)
{

    int* next = new int[T.length + 1];
    get_next(T, next);
    printf("The next is:\n");
    for (int k = 1; k <= T.length; k++) {
        printf("%d  ",next[k]);
    }
    printf("\n");

    int i = 1, j = 1;
    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) {
        return i - T.length;
    }
    else
    {
        return 0;
    }
    delete[]next;
    next = NULL;
}

int Index_KMP_Nextval(SString S, SString T)
{
    int* nextval = new int[T.length + 1];
    get_next(T, nextval);
    printf("The nextval is:\n");
    for (int k = 1; k <= T.length; k++) {
        printf("%d  ", nextval[k]);
    }
    printf("\n");

    int i = 1, j = 1;
    while (i <= S.length && j <= T.length)
    {
        if (j == 0 || S.ch[i] == T.ch[j])
        {
            i++;
            j++;
        }
        else
        {
            j = nextval[j];
        }
    }
    if (j > T.length) {
        return i - T.length;
    }
    else
    {
        return 0;
    }
    delete[]nextval;
    nextval = NULL;
}

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;*/
            next[++i] = ++j;
        }
        else
        {
            j = next[j];
        }
    }
}

void get_nextval(SString T, int nextval[])
{
    int i = 1, j = 0;
    nextval[1] = 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];
        }
    }
}

void CleanString(SString& S)
{
    for (int i = 1; i <= S.length; i++) {
        S.ch[i] = NULL;
    }
    S.length = 0;
}

void ShowString(SString S)
{
    for (int i = 1; i <= S.length; i++) {
        printf("%c", S.ch[i]);
    }
    printf("\n");
}

int main() {
    SString S;
    S.length = 0;

    printf("The String is empty? %d\n", StrEmpty(S));

    if (!StrAssign(S, 'a'))
    {
        printf("Str Assign is error!\n");
    }

    if (!StrAssign(S, 'b'))
    {
        printf("Str Assign is error!\n");
    }

    if (!StrAssign(S, 'c'))
    {
        printf("Str Assign is error!\n");
    }

    if (!StrAssign(S, 'n'))
    {
        printf("Str Assign is error!\n");
    }

    if (!StrAssign(S, 'x'))
    {
        printf("Str Assign is error!\n");
    }

    if (!StrAssign(S, 'y'))
    {
        printf("Str Assign is error!\n");
    }

    printf("The String is empty? %d\n", StrEmpty(S));
    printf("The String length is %d\n", StrLength(S));

    SString T;
    T.length = 0;
    printf("The String is empty? %d\n", StrEmpty(T));
    StrCopy(T, S);
    printf("The String is empty? %d\n", StrEmpty(T));
    printf("The String length is %d\n", StrLength(T));

    SString St;
    St.length = 0;
    if (!Concat(St, S, T)) {
        printf("The St length is small!\n");
    }
    printf("The String is empty? %d\n", StrEmpty(St));
    printf("The String length is %d\n", StrLength(St));

    ShowString(S);
    ShowString(T);
    ShowString(St);

    int flag = StrCompare(S, T);
    //int flag = StrCompare(S, St);
    //int flag = StrCompare(St, T);

    if (flag > 0) {
        printf("The result is S > T\n");
    }
    else if (flag == 0){
        printf("The result is S = T\n");
    }
    else
    {
        printf("The result is S < T\n");
    }

    SString Sub;
    Sub.length = 0;
    SubString(Sub, St, 4, 3);
    ShowString(Sub);

    printf("The sub's pos is %d\n", Index(S, Sub));

    CleanString(S);
    ShowString(S);
    printf("The S is empty? %d\n", StrEmpty(S));
    printf("The String length is %d\n", StrLength(S));

    printf("The sub's pos is %d\n", Index_Simple(St, Sub));

    SString a;
    a.length = 0;

    if (!StrAssign(a, '1'))
    {
        printf("Str Assign is error!\n");
    }

    if (!StrAssign(a, '2'))
    {
        printf("Str Assign is error!\n");
    }
    
    ShowString(a);
    printf("The a's pos is %d\n", Index_Simple(St, a));
    
    /*use next[]*/
    if (Index_KMP_Next(St, Sub) == 0) {
        printf("The sub is not in the St!");
    }
    else
    {
        ShowString(St);
        ShowString(Sub);
        printf("The Sub's pos is %d\n", Index_KMP_Next(St, Sub));
    }

    if (Index_KMP_Next(St, a) == 0) {
        printf("The a is not in the St!");
    }
    else
    {
        ShowString(St);
        ShowString(a);
        printf("The a's pos is %d\n", Index_KMP_Next(St, a));
    }
    
    /*use nextval[]*/
    if (Index_KMP_Nextval(St, Sub) == 0) {
        printf("The sub is not in the St!");
    }
    else
    {
        ShowString(St);
        ShowString(Sub);
        printf("The Sub's pos is %d\n", Index_KMP_Nextval(St, Sub));
    }

    if (Index_KMP_Nextval(St, a) == 0) {
        printf("The a is not in the St!");
    }
    else
    {
        ShowString(St);
        ShowString(a);
        printf("The a's pos is %d\n", Index_KMP_Nextval(St, a));
    }
}

运行结果:

在这里插入图片描述

总结

模式匹配算法比较晦涩,建议先进行理论学习,弄懂算法原理,会求next数组,nextval数组,然后在进行代码复现。可以通过视频讲解学习,这样有助于理解,比较直观。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值