您的位置:首页 > 其它

算法入门之串的顺序存储表示

2011-11-10 16:52 260 查看
串,即字符串。计算机上的非数值处理的对象基本上是字符串数据。但是,由于现在我们使用的计算机硬件结构主要是反映数值计算的需要的,在处理字符串数据时比处理整数和浮点数要复杂的多。而且,对于不同类型程序,所处理的字符串具有不同的特点,要有效地实现字符串的处理,就必须根据具体情况使用合适的存储结构。串的存储表示主要有:1.定长顺序存储表示; 2. 堆分配存储表示; 3.块链存储表示。
以下介绍比较简单的定长顺序存储表示。

串定长顺序存储表示,说白了,就是用以个固定长度字符数组来存放。

1.定义“头部”

#define MAXSTRLEN 255  //所能定义的最大串长
typedef unsigned char SString[MAXSTRLEN + 1]; //数组中下标0的位置,用来存放,当前串的长度

2.初始化

Status InitStr(SString &T)
{
T[0] = 0;//初始化唯一要做的事。定义串当前长度为0。
return OK;
}
3.把一个字符数组赋给SString。。

Status StrAssign(SString &T, char *chars)
{
int len = strlen(chars);
if (len > MAXSTRLEN)
return ERROR;
T[0] = len;
for (int i = 0; i < len; i++)
{
T[i + 1] = chars[i];
}
return OK;
}

也许看到在这,你会问,SString本身是一个字符数组,为什么又要用一个字符数组去赋给SString?

其实不然,SString相对与字符数组,已经有所不同了,它以数组中下标0的位置存放串当前的实际长度。PASCAL语言中就是使用这个串类型的表示方法。

而对于char *chars = "12345",要像把它赋给另一个字符数组如char chars1
,那么这里的n值必须大于等于6。因为C语言在字符串末位加了'\0'作为结束标志符。但是有的编译器如gcc不检测这错误。

4.串的比较

Status StrCompare(SString S, SString T)
{
for (int i = 1; i <= S[0] && i <= T[0]; i++)
{

if (S[i] != T[i])
{
return S[i] - T[i]; //返回第一组不同的字符间的差
}
}
return T[0] - S[0];//若其中一个字符串刚好是另一个的子串,返回两字符串之间的长度差。
}

5.从S下标为pos开始,取长度len的子串Sub。

Status SubString(SString S, SString &Sub, int pos, int len)
{
if (pos < 1 || pos > S[0] || len < 1 || len > S[0] - pos + 1)
return ERROR;
Sub[0] = len;
for (int i = 1; i <= len; i++)
{
Sub[i] = S[pos + i - 1];
}
return OK;
}

6.串的合并:S1,S2合并为S

Status Contact(SString &S, SString S1, SString S2)
{
int i = 0;
int j = 0;
if (S1[0] + S2[0] <= MAXSTRLEN)   //第一种情况,两串长度的和小于所定义的串的最大存储长度
{
S[0] = S1[0] + S2[0];
for (i = 1; i <= S1[0]; ++i)
S[i] = S1[i];
for (j = 1; j <= S2[0]; ++i, ++j)
S[i] = S2[j];
return OK;
} else if (S1[0] < MAXSTRLEN)     //第二种情况,S1能完全存入S,S2可能被截断或者一个都不存入
{

S[0] = MAXSTRLEN;
for (i = 1; i <= S1[0]; i++)
{
S[i] = S1[i];
}
for (j = 1; i <= MAXSTRLEN; ++i, ++j)
S[i] = S2[j];
return OK;
} else)			      //第三种情况,连S1也被截断
{
S[0] = MAXSTRLEN;
for (i = 1; i <= MAXSTRLEN; i++)
{
S[i] = S1[i];
}
return OK;
}
}

7.模式匹配的一种改进算法:KMP算法

void get_next(SString T, int next[])
{
int i = 1;
next[1] = 0;
int j = 0;
while (i < T[0])
{
if (j == 0 || T[i] == T[j])
{
++i;		//执行先++j,再执行next[i] = j。
++j;		//因为是在串中第j+1字符前有长度为j的最长子串,与从首字符起长度为j的子串相等。					next[i] = j;	//注意其上的前提是已经T[i] == T[j]。
} else
j = next[j];
}
}
//S为主串,T为要查找的模式串
Status Index_KMP(SString S, SString T, int pos)
{
int *next = new int();
get_next(T, next);
int i = pos, j = 1; //i为T开始匹配的位置 ,
while (i <= S[i] && j <= T[0])
{
if (j == 0 || S[i] == T[j])
{
++i;
++j;
} else
j = next[j];	//j != 0 且 S[i] != T[j],S[i]与T[next[j]]比较
}
if (j > T[0])
return i - T[0];		//匹配成功
else
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: