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

串,即字符串。计算机上的非数值处理的对象基本上是字符串数据。但是,由于现在我们使用的计算机硬件结构主要是反映数值计算的需要的,在处理字符串数据时比处理整数和浮点数要复杂的多。而且,对于不同类型程序,所处理的字符串具有不同的特点,要有效地实现字符串的处理,就必须根据具体情况使用合适的存储结构。串的存储表示主要有: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],那么这里的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;

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值