串的定长顺序存储及其应用 C语言

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


 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值