xiaoxiao2021-08-17  177

    一 定义

    字符串:是由零个或多个字符串组成的有限序列,又名字符串。一般记为 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; }
    转载请注明原文地址: https://ju.6miu.com/read-676564.html

    最新回复(0)