/*
串的定长顺序存储实现
作者: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;
}