一 定义

字符串:是由零个或多个字符串组成的有限序列,又名字符串。一般记为
s=“a1a2a3a4。。。an”;

子串和主串
子串:串中任意个数的子序列称为改串的子串

二串的比较

计算机中的常用字符的标准为ASCII,由7位二进制数表示一个字符,总共可以表示128个字符。后来出现一些特殊字符,于是ASCII拓展为由8位二进制数表示。

在C语言中比较字符串的大小:
1.相等:串的长度及串中各个位置对应的字符都相等。
2.s< t s=“a1a2a3a4。。。an”; t=“b1b2b3b4。。。bm”;
- n< m,且si = ti
如s=“hap”,t=“happy”
- 存在某个K小于等于min(m,n),使ai=bi,ak < bk
如s=“happes” t=“happy” 字符e的ASCII为101 y的ASCII为121

在C语言中字符串的长度中包含一个‘\0’
串的顺序存储结构
要为串变量分配一个固定长度的存储区,但如两串的连接,字符串的替换,都有可能使串序列超过了数组的长度。

串的链式存储结构
由于串结构的特殊性,如果一个节点时对应一个字符会存在很大的空间浪费。因此一个节点可以存放多个字符,当一个节点未被占满时,可以用“#”或其他非字符串补全。但性能不如顺序存储。

#include "string.h"
#include "stdio.h"
#include "stdlib.h"
#include "io.h"
#include "math.h"
#include "time.h"

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 40 /* 存储空间初始分配量 */

typedef int Status;     /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef int ElemType;   /* ElemType类型根据实际情况而定,这里假设为int */
typedef char String[MAXSIZE+1]; /*  0号单元存放串的长度 */
using namespace std;

Status StrAssign(String T, char* chars){
    int i;
    if(strlen(chars)>MAXSIZE)           //strlen(s)//不包含‘\0’,所以是大于MAXSIZE
        return ERROR;
        T[0] = strlen(chars);
        for(i=1;i<=T[0];i++){
            T[i]=*(chars+i-1);          //char代表首符号的地址
        }
        return OK;
}
/* 返回串的元素个数 */
int StrLength(String S)
{
    return S[0];
}

/* 若S为空串,则返回TRUE,否则返回FALSE */
Status StrEmpty(String S)
{
    if(S[0]==0)
        return TRUE;
    else
        return FALSE;
}

Status StrCopy(String T, String S){
    if(MAXSIZE<S[0]){          //第一位为字符串的长度
        return ERROR;
    }
    T[0] = S[0];
    int i;
    for(i=1;i<=T[0];i++){
        T[i] = S[i];
    }
    return OK;
}

void PrintStr(String S){
    if(S[0]){
        int i=1;
        for(;i<=S[0];i++){
            printf("%c",S[i]);
        }
    }
    printf("\n");
}

Status ClearString(String S){
    if(S[0]==0)
        return ERROR;
    S[0]=0;
    return OK;
}
/*  初始条件: 串S和T存在 */
/*  操作结果: 若S>T,则返回值>0;若S=T,则返回值=0;若S<T,则返回值<0 */
int StrCompare(String T , String S){
    int i = 1;
    while(i<=T[0]&&i<=S[0]){
        if(T[i]!=S[i])
            return S[i]-T[i];
        i++;
    }
    return S[0]-T[0];    //在abcde 和 abcdef的情况下 是相等的
}

/* 用T返回S1和S2联接而成的新串。若未截断,则返回TRUE,否则FALSE */
Status Concat(String T , String S1, String S2){
    int i=1;
    if(S1[0]+S2[0]<=MAXSIZE){
        if(S1[0]){
            for(i=1;i<=S1[0];i++)
                    T[i] = S1[i];
        }
        if(S2[0]){
            for(i=1;i<=S2[0];i++)
                T[i+S1[0]] = S2[i];
        }
        T[0] = S1[0]+S2[0];
        return OK;
    }else{//截断S2
        if(S1[0]&&S1[0]<MAXSIZE){
            for(i=1;i<=S1[0];i++)
                T[i] = S1[i];
        }

        for(i=1;i<=MAXSIZE-S1[0];i++){
            T[i+S1[0]] = S2[i];
        }
        T[0]=MAXSIZE;
        return FALSE;
    }
}

/* 用Sub返回串S的第pos个字符起长度为len的子串。 */
Status SubString(String Sub, String S ,int pos , int len ){
    if(S[0]!=0&&len>=0&&len<=(S[0]-pos+1)&&pos>=1&&pos<=S[0]){   //包含开始的位置
        int i;
        for(i=1;i<=len;i++){
            Sub[i] = S[pos+i-1];
        }
        Sub[0] = len;
    }
    return ERROR;
}
/*  T为非空串。若主串S中第pos个字符之后存在与T相等的子串, */
/*  则返回第一个这样的子串在S中的位置,否则返回0 */
int Index(String S , String T ,int pos){
    if(pos<1)
    return -1;
    int n = S[0];
    int m = T[0];
    String sub;
    int i ;
    i=pos;
    while(i<=n-m+1){ //子字符串需要移动和原字符比较的次数
        SubString(sub,S,i,m);
        if(StrCompare(sub,T)!=0){
            ++i;
        }else{
            return i;
        }

    }
    return 0;
}


int Index1(String S,String T,int position){
    if(position<1&&position>S[0])
        return -1;
    int i = position;
    int j = 1;
    while(i<=S[0]&&j<=T[0]){
        if(S[i] == T[j]){
            i++;
            j++;
        }else{
            i=i-j+2;//i总比j大i-1,原来位置的i+2得到它的下一个位置
            j=1;
        }
    }

    if(j > T[0]){//说明整个T字符串已经匹配上了
        return i-T[0];
    }else{
        return 0;
    }

}

/*  初始条件: 串S和T存在,1pos≤StrLength(S)+1 */
/*  操作结果: 在串S的第pos个字符之前插入串T。完全插入返回TRUE,部分插入返回FALSE */
Status StrInsert(String S, int pos , String T){
    int i;
    if(pos<1||pos>S[0]+1)
        return ERROR;
    if(S[0]+T[0]<=MAXSIZE){
        for(i=S[0];i>=pos;i--) //移动
            S[i+T[0]]=S[i];
        for(i=1;i<=T[0];i++){  //插入
            S[i+pos-1]=T[i];
        }
        S[0]=S[0]+T[0];
        return TRUE;
    }else{
        for(i=MAXSIZE;i>=pos;i--){//将从pos位置开始,T[0]长度的子串,移动到最后一个位置
            S[i]=S[i-T[0]];
            if(i == MAXSIZE-T[0]) //加这个的目的是为了恰好复制需要改变的长度
                                  //MAXSIZE-T[0]为需要复制字符的个数
                break;
        }
        for(i=pos;i<pos+T[0];i++) //再向空出的元素赋值
            S[i]=T[i-pos+1];
        S[0]=MAXSIZE;
        return FALSE;

    }
}

Status StrDelete(String S , int pos ,int len){
    if(pos<1||pos>S[0]||len<0||len>S[0]-pos+1)
        return ERROR;
    int i;
    for(i=pos+len;i<=S[0];i++){  //1 2 3 4 5 6 7 8 9 0 pos=2 len=3 需要删除的元素为234
                                //需要从第2个位置开始复制的是5 6 7 8 9 0 赋值的次数为S[0]-pos+len
        S[i-len] = S[i];
    }
    S[0]=S[0]-len;
    return OK;
}

/*  初始条件: 串S,T和V存在,T是非空串(此函数与串的存储结构无关) */
/*  操作结果: 用V替换主串S中出现的所有与T相等的不重叠的子串 */
Status Replace(String S,String T,String V){
    int Tlength = T[0];
    int i;
    String sub;
    for(i=1;i<=S[0]-Tlength+1;i++){
        SubString(sub,S,i,Tlength);
        if(StrCompare(sub,T)!=0)
            continue;
        else{
            StrDelete(S,i,Tlength);
            StrInsert(S,i,V);
        }
    }
}


/*  初始条件: 串S,T和V存在,T是非空串(此函数与串的存储结构无关) */
/*  操作结果: 用V替换主串S中出现的所有与T相等的不重叠的子串 */
Status Replace1(String S,String T,String V)
{
    int i=1; /*  从串S的第一个字符起查找串T */
    if(StrEmpty(T)) /*  T是空串 */
        return ERROR;
    while(i){
        i=Index(S,T,i); /*  结果i为从上一个i之后找到的子串T的位置 */
        if(i) /*  串S中存在串T */
        {
            StrDelete(S,i,StrLength(T)); /*  删除该串T */
            StrInsert(S,i,V); /*  在原串T的位置插入串V */
            i+=StrLength(V); /*  在插入的串V后面继续查找串T */
        }
    }
    return OK;
}
int main()
{
    String s1,s2,s3,T,sub;
    StrAssign(s1,"abcdefghijklmnopqrstuvwxyz");
    printf("串长为%d 串空否?%d(1:是 0:否)\n",StrLength(s1),StrEmpty(s1));
    StrCopy(s2,s1);
    printf("复制后的字符串为:");
    PrintStr(s2);
    StrAssign(s3,"abcde");
    printf("\ns1与s3比较的结果是:");
    printf("%d\n",StrCompare(s1,s3));
    printf("把s1和s2连接后赋值给T后的结果是:");
    Concat(T,s1,s2);
    printf("串长为%d 串空否?%d(1:是 0:否)\n",StrLength(T),StrEmpty(T));
    PrintStr(T);
    printf("\n拷贝在T中从3起到长度为8的子串:\n");
    SubString(sub,T,3,8);
    PrintStr(sub);
    printf("\n在S中找到与T字符串相等的字符串的位置为\n");
    int position = Index(T,sub,1);
    printf("%d\n",position);
    String a,b;
    StrAssign(a,"123456789abcdefghijklmnopqrstuvwxz12345");
    printf("串长为%d 串空否?%d(1:是 0:否)\n",StrLength(a),StrEmpty(a));
    PrintStr(a);
    StrAssign(b,"0000000000");
    printf("\n");
    printf("在第7个位置前插入字符串\n");
    StrInsert(a,7,b);
    PrintStr(a);
    printf("在第七个位置上删除长度为10的子字符串的结果为\n");
    //StrDelete(a,7,10);
    PrintStr(a);
    printf("将r1中与r2相等的子串替换为r3\n");
    String r1,r2,r3;
    StrAssign(r1,"aabbccddeeaabbccddeeaabb");
    StrAssign(r2,"aa");
    StrAssign(r3,"00000");
    printf("r1= ");PrintStr(r1);
    printf("r2= ");PrintStr(r2);
    printf("r3= ");PrintStr(r3);
    Replace1(r1,r2,r3);
    PrintStr(r1);

return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值