顺序串的基本操作及朴素模式算法——C语言

/*
    串基于顺序存储结构的实现
    串是一种特殊的线性表,但与线性表不同之处在于对串的操作往往是在子串上实现
    结构体要求:数据域:char型
    要实现的方法:
    字符串的基本操作,大小比较及朴素模式匹配算法
*/ 

#include <stdio.h>
#include <stdlib.h>

#define MAXSIZE 255 //最大空间

typedef struct{//串的顺序存储结构体 
    char ch[0+MAXSIZE];//0位置不用(为保证序号与下标一致)
    int length; //串的当前长度 
}SString;

//方法体
    //创
    bool InitSString(SString &S){//初始化串 
        S.length = 0;//将串长初始化为0;
        return true; 
    } 

    void CreateSString(SString &S){//创建字符串 
        InitSString(S);
        printf("\n请输入要创建的字符串,输入#结束\n");
        char in;
        scanf("%c",&in);
        while(in!='#'&&S.length<MAXSIZE){
            S.ch[++S.length] =  in;
            scanf("%c",&in);
        }
        getchar();//必须要有这步吸收换行符,否则创建第二个字符串T的时候会导致,T的首字符为换行符 
    }
    
    //增,在第i个位置增加字符in 
    bool InsertSString(SString &S,int i,char in){
        if(i<0||i>S.length+1){
            printf("\n插入的位置有误!\n");
            return false;
        }else if(S.length==MAXSIZE){
            printf("\n串已满!\n");
            return false;
        } 
        //输入的位置正确,开始进行插入操作 
        int j = ++S.length;//方便移动数组元素 
        while(j>i){//移动后让j自减 
            S.ch[j] = S.ch[j-1];
            j--;
        } 
        //循环结束后,i位置的空间就会空出来,此时直接插入目标值in 
        S.ch[i] = in;
        return true;
    }
    
    //删,与增加字符类似,但移动的方向相反 
    bool DeleteSString(SString &S,int i){
        if(S.length==0||i<0||i>S.length){
            printf("\n字符串已空!\n");
            return false;
        }
        //输入的位置正确,开始进行删除操作 
        while(i<S.length){//移动后让j自减 
            S.ch[i] = S.ch[i+1];
            i++;
        } 
        //循环结束后,该位置便被删除,长度应减1 
        S.length--;
        return true;
    }
    //查 
    bool ShowSString(SString S){//查询所有字符串元素 
        if(S.length==0){//判断串是否为空串 
            printf("\n字符串为空!\n");
            return false;
        }
        //串非空,开始输出字符串内容 
        int i = 1;
        printf("\n字符串为:\n");    
        while(i<=S.length){
            printf("%c",S.ch[i++]);
        } 
    } 
    
    //找子串,为模式匹配做准备 
    bool SubString(SString &Sub,SString S,int sta,int len){//从sta位置开始,找长度为len的字符串 
        if(sta+len-1 > S.length){
            printf("\n\n子串大小超过主串!\n");
            return false;
        }
        //可找到子串,开始赋值子串给Sub 
        for(int i=sta; i < sta+len;i++){
            Sub.ch[i-sta+1] = S.ch[i];//赋值给子串 
        } 
        //赋值成功 
        Sub.length  = len;
        return true;
    }

    //比较两子串的大小关系(返回值大于0则前者大于后者,等于则相等) 
    int StrCompare(SString S,SString T){
        for(int i=1; i<=S.length&&i<=T.length; i++){
            if(S.ch[i]!=T.ch[i])//找到第一个字符不相等的位置,则直接返回它两的ASCII码差值 
                return (S.ch[i] - T.ch[i]);//如果大于0则说明前者大于后者 
        }
        //始终没找到不相等的字符,直接返回两者的字符长度差值
        return S.length - T.length;//直接返回两者的大小长度 
    }
    
    //模式匹配算法,需要使用大小匹配和找子串功能 
    int Index(SString S,SString ser){//找到ser串在主串S中是否出现过,并返回首次出现的位置 
        int i =1;//ser串可能出现的首位置 
        int n = S.length,m = ser.length;
        SString Sub;//模式匹配的子串 
        while(i+m <= n+1){//当首位置加查找的子串长 > 主串长度加1时应结束循环 
            SubString(Sub,S,i,m);//从i开始从主串中依次找到对应的子串 
            if(StrCompare(Sub,ser)!=0) i++;//看模式串跟目标串是否相等,不等则i自增,相等则返回首位置i 
            else{
                printf("目标首元素在第%d个位置",i);
                return i;
            } 
        }
        //若没找到,则返回0
        printf("未找到目标!\n");
        return 0; 
    }
    
    
int main(){
    SString S;
    CreateSString(S);
    ShowSString(S);
    
//    printf("\n\n插入元素测试");
//    InsertSString(S,3,'M');
//    ShowSString(S);
//    
//    printf("\n\n删除元素测试");
//    DeleteSString(S,3);
//    ShowSString(S);
//    
//    子串功能测试 
//    printf("\n\n找子串测试");
//    SString Sub;
//    SubString(Sub,S,2,3);
//    ShowSString(Sub);    
    
    
// 大小比较测试 , 这里时不时开始出现乱码,而且只能输出S>T 
    printf("\n大小比较测试");
    SString T;
    printf("\n请输入要比较的新字符串:");
    CreateSString(T);
    int result = StrCompare(S,T);
    if(result>0){
        printf("S>T\n");
    }else if(result==0){
        printf("s=t\n");
    }else{
        printf("S<T\n");
    }


// 模式匹配算法测试
    printf("\n模式匹配算法测试\n");
    SString ser;
    CreateSString(ser);
    Index(S,ser); 


 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值