8、串的顺序存储
1、代码实现
#include<stdio.h> #include<malloc.h> #include<assert.h> #include<string.h> //"abcdef" => "abcdef/0 // 用数组第一个空间存储字符串长度 5 a b c e f #define MAX_STR_LEN 20 #define u_char unsigned char //串结构顺序存储定义 typedef u_char StackString[MAX_STR_LEN + 1];//多一个存储'\0' //初始化 void initString(StackString S){ S[0] = '\0'; } //赋值 void strAssign(StackString S,char *str){ int len = strlen(str); int i = 0; for(i;i < len;i++){ S[i] = str[i]; } S[len] = '\0'; } //拷贝 void strCopy(StackString S,StackString T){ int len = strlength(T); int i = 0; for(i;i < len;i++){ S[i] = T[i]; } S[len] = '\0'; } //长度 int strlength(StackString S) { int len = 0; while(*S != '\0'){ len++; S++; } return len; } //判空 int StrEmpty(StackString S) { return S[0] == '\0'; } //比较[S > T => 1 ; S == T => 0 ; S < T => -1] int StrCompare(StackString S,StackString T){ int result = 0; while(*S != '\0' || *T != '\0'){ result = *S - *T; if(result != 0) break; S++; T++; } if(result > 0) result = 1; else if(result < 0) result = -1; return result; } //连接 串s1 和 串s2 并赋值给 Y void StrConcat(StackString Y,StackString s1,StackString s2) { int len1 = strlength(s1); int len2 = strlength(s2); if(len1 + len2 <= MAX_STR_LEN){ //如果两个串长度相加不超过最大长度 //两个都可以拷贝进去 int i = 0; int j = 0; for(i;i < len1;i++){ Y[i] = s1[i]; } for(j;j < len2;j++){ Y[i + j] = s2[j]; } Y[len1 + len2] = '\0'; }else if(len1 < MAX_STR_LEN){ //s1都拷贝,s2部分拷贝 int i = 0; int j = 0; for(i;i < len1;i++){ Y[i] = s1[i]; } for(j;j < MAX_STR_LEN - len1;j++){ Y[i + j] = s2[j]; } Y[MAX_STR_LEN] = '\0'; } else{ //只能拷贝s1 int i = 0; for(i;i < MAX_STR_LEN;i++){ Y[i] = s1[i]; } Y[MAX_STR_LEN] = '\0'; } } //从S的 pos开始剪切len长度 的子串给sub void SubString(StackString S,StackString sub,int pos,int len){ int s_len = strlength(sub); if(pos < 0 || pos >= len || len < 0 || len > s_len) return; int i = 0; for(i;i < len;i++){ sub[i] = S[pos + i]; } sub[len] = '\0'; } void StrInsert(StackString S,int pos,StackString T){ int s_len = strlength(S); int t_len = strlength(T); if(s_len + t_len <= MAX_STR_LEN){ int i = s_len - 1; //先把S的pos位置之后的元素挪动到后面 for(i;i >= pos;i--){ S[i + t_len] = S[i]; } int j = pos; for(i = 0;i < t_len;i++){ S[j + i] = T[i]; } S[s_len + t_len] = '\0'; } else if(s_len < MAX_STR_LEN){ //只能拷贝T的部分 int i = s_len - 1; //先把S的pos位置之后的元素挪动到后面 for(i;i >= pos;i--){ S[i + t_len] = S[i]; } //不能完全拷贝T 只能拷贝T的部分 t_len = MAX_STR_LEN - s_len; int j = pos; for(i = 0;i < t_len;i++){ S[j + i] = T[i]; } S[s_len + t_len] = '\0'; } } //在S串pos位置删除len长度字符 void strDelete(StackString S,int pos,int len) { int s_len = strlength(S); int i = pos; for(i;i < s_len;i++){ S[i] = S[i + len]; } S[s_len - len] = '\0'; } void strClear(StackString S){ S[0] = '\0'; } void printString(StackString S){ printf("%s\n",S); } //模式匹配[注意:计算机中存储的是0 1,模式匹配算法在计算机中很有用] int strIndex(StackString S,StackString T,int pos){ int i = pos; int j = 0; while(S[i] != '\0' && T[j] != '\0'){ if(S[i] == T[j]){ i++; j++; } else { //i回到开始下标的下一个 i = i - j + 1; j = 0; } } if(T[j] == '\0') return i - j; return -1; } //把主串S中的 子串T 全部换成 子串V void strReplace(StackString S,StackString T,StackString V){ int s_len = strlength(S); int t_len = strlength(T); int v_len = strlength(V); int index = -1; int pos = 0; while(pos < s_len){ index = strIndex(S,T,pos); if(index == -1){ return; } //先删除 strDelete(S,index,t_len); //在插入 StrInsert(S,index,V); //更改下一次匹配的位置为 上一次匹配的位置 + 字串V的长度 pos = index + v_len; } } int main(){ StackString S;// =>unsigned char[MAX_STR_LEN + 1] strAssign(S,"abqwqcdefqwqss"); printString(S); // StackString sub; // strAssign(sub,"123"); // StrInsert(S,2,sub); // printString(sub); // StackString T; // strAssign(T,"adaaa"); // int i = strIndex(S,T,0); // printf("%d",i); StackString T; initString(T); strAssign(T,"qwq"); StackString V; initString(V); strAssign(V,"ovo"); strReplace(S,T,V); printString(S); return 0; }