/* 串的定长顺序存储实现 作者:S_hmily 日期:2011年9月1日 编译环境:VC++6.0 */ /****************************************************/ #include <stdio.h> /****************************************************/ #define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0 typedef int ElemType; typedef int Status; #define MaxSize 255 typedef unsigned char SString[MaxSize+1]; /****************************************************/ //初始化 必须初始化 否则判空无法完成 Status InitStr(SString S) { S[0] = 0; return OK; } /****************************************************/ //创建 Status CreateStr(SString S, char chars[]) { int i; for (i=0; chars[i]!='\0' && i+1<MaxSize; ++i) S[i+1] = chars[i]; S[0] = i; return OK; } /****************************************************/ //输出 void DispStr(SString S) { int i; for (i=1; i<=S[0]; ++i) putchar(S[i]); putchar('\n'); } /****************************************************/ //串拷贝 Status StrCopy(SString T, SString S) { int i; for (i=1; i<=S[0]; ++i) T[i] = S[i]; T[0] = S[0]; return OK; } /****************************************************/ //串判空 Status StrEmpty(SString S) { if (0 == S[0]) return TRUE; else return FALSE; } /****************************************************/ //若S大于T 返回值>0 若S等于T 返回值=0 若S小于T 返回值<0 //如果T串是以S串开头的主串 只能返回0 //如果S串是以T串开头的主串 可能返回不确定值 //所以该函数应该是再判断了双方都不是对方的子串的时候才使用 int StrCompare(SString T, SString S) { int i, n=0; for (i=1; i<=S[0]; ++i) { if (S[i] != T[i]) { n = S[i] - T[i]; break; } } return n; } /****************************************************/ //求串长 int StrLength(SString S) { return S[0]; } /****************************************************/ //串清空 Status ClearStr(SString S) { S[0] = 0; return OK; } /****************************************************/ //串连接 Status Concat(SString T, SString S1, SString S2) { int i, k; for (i=1; i<=MaxSize && i<=S1[0]; ++i) T[i] = S1[i]; k = i-1; T[0] = k; for (i=1; i+k<=MaxSize && i<=S2[0]; ++i) T[i+k] = S2[i]; T[0] += i-1; return OK; } /****************************************************/ //T中存入S串中第pos个位开始的len个字符组成的子串 Status SubStr(SString Sub, SString S, int pos, int len) { int i; if (pos<1 || len<0 || pos+len-1>S[0]) return ERROR; for (i=1; i<=len; ++i) { Sub[i] = S[pos+i-1]; } if (0 == len) Sub[0] = 0; else Sub[0] = i-1; return OK; } /******************************************************/ //在S串中的第pos个位之前插入串T //因为该函数中所有调用到的其他子函数都有做长度的判断 //所以该函数不需要再判断 只做pos有效性的判断 Status StrInsrt(SString S, int pos, SString T) { SString New; SString Temp; if (pos<1 || pos>S[0]) return ERROR; SubStr(Temp, S, 1, pos-1); Concat(New, Temp, T); SubStr(Temp, S, pos, S[0]-pos+1); Concat(S, New, Temp); return OK; } /****************************************************/ //删除S串中第pos位开始的len个字符 Status StrDelete(SString S, int pos, int len) { SString Temp; SString Sub; if (pos<1 || pos+len>S[0]+1) return ERROR; SubStr(Temp, S, 1, pos-1); SubStr(Sub, S, pos+len, S[0]-pos-len+1); Concat(S, Temp, Sub); return OK; } /****************************************************/ //S中从pos位开始是否有与T串相同的子串 //串的模式匹配 朴素算法的实现 Status Index_BF(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; j = 1; } } if (j > T[0]) return i-T[0]; else return 0; } /****************************************************/ GetNext(SString T, int next[]) { int i = 1; int j = 0; next[1] = 0; while (i < T[0]) { if (j==0 || T[i]==T[j]) { ++i; ++j; if (T[i] != T[j]) next[i] = j; else next[i] = next[j]; } else j = next[j]; } } /****************************************************/ Status Index_KMP(SString T, SString S, int pos) { int i = pos; int j = 1; int next[MaxSize]; GetNext(S, next); while (i<=T[0] && j<=S[0]) { if (j==0 || T[i]==S[j]) { ++i; ++j; } else j = next[j]; } if (j>S[0]) return i-S[0]; else return 0; } /****************************************************/ int main(void) { SString T, S1, S2; int i; InitStr(T); InitStr(S1); InitStr(S2); CreateStr(S1, "ABCDEFGH"); CreateStr(S2, "GH"); i = Index_KMP(S1, S2, 3); printf("%d\n", i); return 0; }