计算机上的非数值处理的对象基本上是字符串数据。在较早的程序设计语言中字符串是作为输入输出的常量出现的。随着语言加工程序的发展,产生了字符串处理。这样,字符串就作为一种变量类型出现在越来越多的程序设计语言中,同时也产生了一系列字符串的操作。字符串简称为串。在汇编和语言的编译程序中,源程序和目标程序都是字符串数据。在事务处理程序中,顾客的姓名和地址以及货物的名称、产地和规格等一般也是作为字符串处理的。又如信息检索系统、文字编辑程浮点数序、问答系统、自然语言翻译系统以及音乐分析程序等,都是以字符串数据作为处理对象的。
然而,现金我们使用的计算机硬件结构主要是反映数值计算的需要的,因此,在处理字符串数据的时候比处理整数和复杂的多。而且,在不同类型的应用中,所处理的字符串具有不同的特点,要有效的实现字符串的处理,就必须根据具体情况使用合适的存储结构。
4.1 串类型的定义
串是由零个或多个字符组成的有限序列,一般记为
s = `abcde…z`
其中s是串的名,用单引号括起来的字符序列是串的值;串中任意个连续字符组成的子序列称为该串的子串。两个串相等是指两个串的值相等,就是单引号里面的字符是完全一样的。由一个或多个空格组成的串称为空格串;它的长度由串中空格的个数决定。
串的逻辑结构和线性表极为相似,区别在于串的数据对象限定为字符集。然而,串的操作和线性表的操作区别很大:线性表一般以单个元素作为操作对象;而串一般以串的整体作为操作对象如查找某个子串、求取一个子串、在串某个位置插入一个子串及删除一个子串等。
串的抽象数据类型定义如下:
ADT String{
数据对象:D = {ai | ai ∈CharacterSet,i = 1,2……,n,n >=0}
数据关系:R1 = {<a(i-1) , ai> | a(i-1), ai ∈D,i = 1,2,……,n}
基本操作:
StrAssign(&T,chars)
操作结果:生成一个其值等于chars的串T。
StrCopy(&T,S)
操作结果:把字符串S的值拷贝给串T 。
StrEmpty(S)
操作结果:若串S为空返回TURE,否则返回ERROR。
StrCompare(S,T)
操作结果:若S>T,返回值>0;S=T,返回值=0;S<T,返回值<0。
StrLength(S)
操作结果:返回串的长度。
ClearString(&S)
操作结果:清空串S。
Concat(&T,S1,S2)
操作结果:用串T返回由串S1和S2联接成的新串。
SubString(&sub,S,pos,length)
操作结果:用串sub返回串S第pos位置开始的length个字符长度的子串。
Index(S,T,pos)
操作结果:如果在串S中存在和串T相等的子串,那么在串S的pos位置后面子串出现的位置,否则函数值为0。
Replace(&S,T,V)
操作结果:用V替代主串S中出现的所有不重叠的和T相等的子串。
StrInsert(&S,pos,T)
操作结果:在串S的位置之前插入串T。
StrDelete(&S,pos,length)
操作结果:删除串S的第pos个位置起的length个长度的字符。
DestoryString(&S)
操作结果:销毁串S。
}ADT String
在上述13中类型串操作中由5中类型构成了串类型的最小操作子集,分别是:StrAssign、StrCompare、Concat、SubString和StrLength。即这些操作不肯能利用其它串操作来实现,反之,其它串操作均可在这个最小操作子集上实现。
例如,可以利用判等、求串长和求子串等实现定位函数Index。
算法的基本思想是:在串S中第i个字符起取与子串T长度相等的子串与T比较,相等,则求的函数值为i,否则i值增1,直到S中不存在和子串T相等的子串为止。
int Index(String S,String T,int pos)
{
if(pos > 0)
{
n = StrLength(S); m = StrLength(T); i = pos;
while(i < n-m+1)
{
SubString(sub,S,i,m);
if(StrCompare(sub,T) != 0) ++i;
else retrun i;
}
}
return 0;
}