(第四章)串的基本操作

头文件 

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

 定义串的结构体

typedef struct
{
    char * ch;
    int length;
}HString;

(1)串的初始化 

void Init_String(HString * s)  //初始化
{
    s->ch=NULL;
    s->length=0;
}

(2)赋值,把串str复制到串s 

short StrAssign(HString * s, char * str)  //赋值
{
    int i;
    int len=strlen(str);
    free(s->ch);
    s->ch=(char*)malloc(sizeof(char)*len);
    if(s->ch==NULL)
        return 0;
    for(i=0; i<len; i++)
    {
        s->ch[i]=str[i];
    }
    s->length=len;
    return 1;
}

(3)打印串 

void Print(HString * s)  //打印
{
    int i;
    for(i=0; i<s->length; i++)
    {
        printf("%c", s->ch[i]);
    }
    printf("\n");
}

(4)复制操作,由串s复制得到串p 

void StrCopy(HString * p, HString * s)  //由串s复制得到串p
{
    int i;
    p->ch=(char*)malloc(sizeof(char));
    for(i=0; i<s->length; i++)
    {
        p->ch[i]=s->ch[i];
    }
    p->length=s->length;
}

(5) 判断串是否为空

short StrEmpty(HString * s)  //判断是否为空
{
    if(s->length==0)
        return 1;
    else
        return 0;
}

(6) 比较两串长度,s大于p返回1,小于返回-1,等于返回0

short StrCompare(HString * s, HString * p)  //比较两串长度
{
    int i=0;
    int j=0;
    if(s->length==0 && p->length==0)
        return 0;
    while(i<s->length && j<p->length)
    {
        if(s->ch[i] > p->ch[i])
            return 1;
        else if(s->ch[i] < p->ch[i])
            return -1;
        else
        {
            i++;
            j++;
        }
    }
    if(i<s->length)
        return 1;
    else 
        return -1;
}

(7) 返回串长度

int StrLength(HString * s)  //返回串长度
{
    return s->length;
}

(8)求子串

void  SubString(HString * sub, HString * s, int pos, int len)  //求子串
{
    int i;
    int j=pos;
    if(pos<0 || pos>s->length || len<0 || len>s->length-pos+1)
        return;
    if(sub->ch!=NULL)
        free(sub->ch);
    sub->ch=(char*)malloc(sizeof(char)*len);
    for(i=0; i<len; i++)
    {
        sub->ch[i]=s->ch[j+i];
    }
    //sub->ch[i+1]='\0';
    sub->length=len;
}

(9)串连接 

void Concat(HString * T, HString * s1, HString * s2)  //s1和s2连接
{
    int len;
    int i,j;
    if(T->ch!=NULL)
        free(T->ch);
    len=s1->length+s2->length;
    T->ch=(char*)malloc(sizeof(char)*len);
    for(i=0; i<s1->length; i++)
    {
        T->ch[i]=s1->ch[i];
    }
    for(j=0; j<s2->length; j++)
    {
        T->ch[j+i]=s2->ch[j];
    }
    T->length=len;
}

(10)定位操作,若主串s中存在与串p相同值的子串,则返回它在主串s中第一次出现的位置;否则函数值为0

int Index(HString s, HString p)  //定位操作(朴素模式匹配算法)
{
    int i=1, j=1;
    while(i<=s.length && j<=p.length)
    {
        if(s.ch[i]==p.ch[j])
        {
            i++;
            j++;
        }
        else
        {
            i=i-j+2;
            j=1;
        }
    }
    if(j>p.length)
        return i-p.length;
    else
        return 0;
}

(11)清空串 ,将s清位空串

void ClearString(HString * s)  //清空串
{
    s->length=0;
    if(s->ch!=NULL)
        free(s->ch);
    s->ch=NULL;
}

(12)销毁串 

void DestroyString(HString * s)  //销毁串
{
    free(s->ch);
}

(13)KMP匹配算法求next数组

void get_next(HString p, int next[])  //KMP匹配算法求next数组(数据多了数组就有点问题,还没有排查出)
{
    int j=0;  //前缀
    int i=1;  //后缀
    next[1]=0;
    while(i<p.length)
    {
        if(j==0 || p.ch[i]==p.ch[j])
        {
            ++i; 
            ++j;
            next[i]=j;
        }
        else
            j=next[j];
    }
}

(14) KMP匹配算法定位

int Index_KMP(HString s, HString p)  //KMP匹配算法
{
    /*不能使用:int next[p.length+1]
    原因:如果一个数组大小是变量定义,则在程序运行前不能确定数组大小,也就无法申请,故不允许*/
    int * next=(int*)malloc(sizeof(int)*(p.length+1));
    int i=1, j=1;
    get_next(p,next);
    while(i<=s.length && j<=p.length)
    {
        if(j==0 || s.ch[i]==p.ch[j])
        {
            ++i;
            ++j;
        }
        else
            j=next[j];
    }
    if(j>p.length)
        return i-p.length;
    else
        return 0;
}

(15) 打印next数组

void Print_next( HString p, int next[])  //打印next数组
{
    int n;
    for(n=1; n<=p.length; n++)  
    {
        printf("%d", next[n]);
    }
    printf("\n");
}

主函数: 

main()
{
    HString s, p, sub, T;
    HString s1, s2; 
    int n; int next[30];
    int pos=0; int len=4;
    char str[20]="abcaaba";
    char st[10]="aaba";
    s.ch=(char*)malloc(sizeof(char));
    p.ch=(char*)malloc(sizeof(char));

    Init_String(&s);
    Init_String(&p);
    Init_String(&sub);
    Init_String(&T);
    Init_String(&s1);
    Init_String(&s2);

    StrAssign(&s, str);
    StrAssign(&p, st);

    printf("(1)打印串s :");
    Print(&s);

    printf("(2)打印串p :");
    /*StrCopy(&p, &s);*/
    Print(&p);

    printf("(3)判断串是否为空:");
    if(StrEmpty(&s))
        printf("串s为空\n");
    else
        printf("串s不为空\n");

    printf("(4)比较串s和串p的长度:");
    if(StrCompare(&s, &p)==1)
        printf("串s>串p\n");
    else if(StrCompare(&s, &p)==0)
        printf("串s=串p\n");
    else
        printf("串s<串p\n");

    printf("(5)s串长:%d\n", StrLength(&s));
    
    printf("(6)求子串:");
    SubString(&sub, &s,pos,len);  //sub记得初始化
    Print(&sub);

    printf("(7)连接s和p,用T返回:");
    Concat(&T, &s, &p);
    Print(&T);

    printf("(8)朴素算法定位:%d\n",Index(s, p));  //串的第一位废弃不用

    //printf("(9)清空串\n");
    //ClearString(&s);
    //
    //printf("(10)销毁串\n");
    //DestroyString(&s);

    printf("(11)KMP算法得到next数组:");  
    get_next(p, next);
    Print_next(p, next);

    printf("(12)KMP算法定位:%d\n",Index_KMP(s, p));  //运行此行代码时记得注释(9)(10),否侧匹配失败
}

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值