#include<bits/stdc++.h> #define ERROR 0 #define OK 1 #define MAXSTRLEN 255 #define FALSE 0 using namespace std; typedef char SString [MAXSTRLEN+1]; ///用0号下标 SString[0] 来存字符串长度 typedef int Status; ///1、将字符串 chars[] 赋给开辟的空间串 T[] Status StrAssgin(SString &T, char chars[]) { ///判断:当 chars[] 的长度大于开辟的空间时返回ERROR int n = strlen(chars); if(n > MAXSTRLEN) { printf("长度不合法,超范围!\n"); return ERROR; } T[0] = n; for(int i = 1; i <= n; i++) { T[i] = chars[i-1]; } return OK; } /// 2、求串长度 int StrLength(SString T) { return T[0]; } ///3、串比较 /* 当S > T ,返回值 >0, 当S = T ,返回值 =0, 当S < T ,返回值 <0, */ int StrCompare(SString S,SString T) { int ans; for(int i = 1; i <= S[0] && i <= T[0]; i++) { if(S[i] != T[i]) { ans = S[i] - T[i]; } else ans = 0; } return ans; } ///4、串的连接 将 串 S1 和 S2 连接到一起赋给空串 T /* 注意:是先将串 S1 放入空串 T ,再存串 S2,所以有几种情况 √ √ √ 1、当 S1 和 S2 的长度和小于 MAXSTRLEN,都存进去 √ √ √ 2、当 S1 的长度小于 MAXSTRLEN 时,但加上 S2 的长度就超过 MAXSTRLEN,则串T的后一段是 S2 的一个子串 截断 ××××× 3、当 S1 的长度大于 MAXSTRLEN 时,我刚开始想的是T内存的时S1的子串, 但是 注意 注意 注意 如果分情况一直顺下来,很容易犯错误 而且<完全错误>, 错误的原因:在初始化一个串的时候 已经 定义过如果长度大于 MAXSTRLEN 则返回 ERROR ,是一个不合法的情况 √ √ √ 4、当 S1 的长度等于 MAXSTRLEN 时,则和 S1 相等 */ Status StrConcat(SString &T, char chars1[], char chars2[] ) { bool flag = true; int i,j; int n1 = chars1[0]; int n2 = chars2[0]; if( (n1 + n2) <= MAXSTRLEN) { ///画个图超级好理解 for(i = 1; i <= n1; i++) { T[i] = chars1[i]; } for(j = 1; j <= n2; j++) { T[n1 + j] = chars2[j]; } T[0] = n1 + n2; flag = true; } else if(n1 < MAXSTRLEN) { T[0] = MAXSTRLEN; for(int i = 1; i <= n1; i++) { T[i] = chars1[i]; } for(j = 1; j <= MAXSTRLEN-n1; j++) { T[n1 + j] = chars2[j]; } flag = false; } else { T[0] = n1; for(int i = 1; i <= n1; i++) { T[i] = chars1[i]; } flag = false; } return flag; } ///5、求子串 /* 条件: 1 <= pos <= Strlength(S) 且 0 <= len <= Strlength(S)-len+1 用 Sub 返回串S的第pos个字符起长度为 len 的子串 */ Status SubString(SString &Sub, SString S, int pos, int len) { if( pos < 1 || pos > S[0] || len < 0 || len > S[0] - pos + 1) return ERROR; for(int i = 1; i <= len; i++) { Sub[i] = S[pos + i - 1]; } Sub[0] = len; return OK; } ///6 索引 /*若主串中存在和子串相同的串,则返回其在主串中第pos个字符之后第一次出现的位置,否则函数为0*/ int Index (SString S, SString T, int pos) { if(pos > 0) { int s = StrLength(S); int t = StrLength(T); int i = pos; while(i <= s - t + 1) { SString sub; SubString(sub,S,i,t); /* 若用库函数strcmp(),要加以下 有结束字节'\0' 的 两条语句,否则库函数无法判断结束条件 sub[t+1]='\0'; T[t+1]='\0'; */ if(StrCompare(sub,T) != 0) ++i; else return i; } } else return 0; } /*或者 int Index (SString S, SString T, int pos) { int i = pos; int j = 1; while(i <= S[0] && j <= T[0]) { if(S[i] == T[j]) { i++; j++; } else { i = i - j + 2; // i退回到上次匹配首位的下一位 比如 主串:ABDABCD 子串:ABC 当 i = j = 3 时,进入else语句 i变为 2, 从第二个开始往下匹配, j = 1; S[2] = B != T[1] = A 所以 i = 2-1+2 = 3 从S[3]开始,直到 i = j = 4 j 已经大于子串的长度,就退出while j = 1; //子串每次从头开始 } } if(j > T[0]) return i-T[0]; else return 0; } */ ///7、串拷贝 Status StrCopy(SString &T,SString S) { for(int i = 1; i <= S[0]; i++) { T[i] = S[i]; } T[0] = S[0]; return OK; } ///8、判断串是否为空 Status StrEmpty(SString &S) { if(S[0] == 0) { printf("串为空\n"); return true; } else { printf("NO 空\n"); return false; } } ///9、清空字符串 Status ClearString(SString S) { S[0] = 0; return OK; } ///10、插入子串T到主串S中的pos位置之前 1 <= pos <= S[0]+1 Status StrInsert(SString &S, int pos, SString T) { if(pos > S[0]) pos = S[0] + 1; if(T[0] + S[0] <= MAXSTRLEN) { for(int i = T[0] + S[0]; i >= pos + T[0]; i--) { S[i] = S[i - T[0]]; } for(int i = pos; i < T[0] + pos; i++) { S[i] = T[i - 1]; } S[0] = S[0] + T[0]; return OK; } } ///11、删除子串,删除第pos位置起的长度为len的子串 Status StrDelete(SString &S, int pos, int len) { for(int i = pos + len; i <= S[0]; i++) { S[i-len] = S[i]; } S[0] = S[0] - len; return OK; } ///12、输出串 Status Print(SString S) { for(int i = 1; i < S[0];i++) { cout<<S[i]<<" "; } cout<<S[S[0]]<<endl; return OK; }