数据结构-线性表-串

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/suxiaorui/article/details/101100977

串的定义

串(string)是由零个或多个字符组成的有限序列,又名叫字符串。

一般记为 s = “ a_{1}a_{2}......a_{n} ”(n≥0),其中,s 是串的名称,用双引号括起来的字符序列是串的值。

串中的字符数目n称为串的长度。零个字符的串称为空串(null string)。它的长度为零,可以直接用两个双引号表示,也可以用希腊字母“φ‘’表示。

空格串:是只包含空格的串,空格串是有长度的,而且可以不止一个空格。

子串:串中任意个数的连续字符组成的子序列称为该串的子串。

主串:包含子串的串称为主串。

串的比较

事实上,串的比较是通过组成串的字符之间的编码来进行的,而字符的编码指的是字符在对应字符集中的序号。

在c语言中,判断两个串是否相等:必须是它们串的长度以及它们各个对应位置的字符都相等,才算是相等。

对于两个不相等的串,s = “a_{1}a_{2}......a_{n}”,t = “b_{1}b_{2}......b_{m}”,当满足以下条件之一时,s < t 。

1. n < m , 且a_{i} = b_{i} (i = 1,2,3, ......, n)。

例如,s = “lo”,t = “love”,就有s < t ,因为 t 比 s 多了两个字母。

2. 存在某个 k ≤ min(m,n),使得 a_{i} = b_{i} (i = 1,2,3,......,k - 1),a_{k}<b_{k}

例如,当 s = “happen”,t = “happy”,因为两串的前4个字母相同,而第5个字母,字母 e 的 ASCII 码是101,而字母 y 的 ASCII 码是121,显然 e < y,所以 s< t 。

串的抽象数据类型

ADT 串 (String)

Data
	串中的元素仅由一个字符组成,相邻元素具有前驱和后继关系.
	
Operation
StrAssign (&T, chars)
	初始条件:chars是字符串常量。
	操作结果:生成一个其值等于chars的串T。
StrCopy (&T, S)
	初始条件:串S存在。
	操作结果:由串S复制得串T。
StrEmpty(S)
	初始条件:串S存在。
	操作结果:若S为空串,则返回TRUE,否则返回FALSE。 
StrCompare(S, T)
	初始条件:串S和T存在。
	操作结果:若S>T,则返回值>0;若S=T,则返回值=0;若S < T,则返回值 < 0。
StrLength(S)
	初始条件:串S存在。
	操作结果:返回S的元素个数,称为串的长度。
ClearString (&S)
	初始条件:串S存在。
	操作结果:将S清为空串。
Concat (&T, S1, S2)
	初始条件:串S1和S2存在。
	操作结果:用T返回由S1和S2联接而成的新串。
SubString(&Sub, S, pos, len)
	初始条件:串S存在,1≤pos≤StrLength(S)且0≤len≤StrLength(S)-pos+1
	操作结果:用Sub返回串S的第pos个字符长度为len的子串。
Index(S, T, pos)
	初始条件:串S和T存在,T是非空串,1≤pos≤StrLength(S)。
	操作结果:若主串S中存在和串T值相同的子串,则返回它在主串S中第pos个字符之后第一次出现的位置;否则函数值为0。
Replace (&S, T, V)
	初始条件:串S, T和V存在,T是非空串。
	操作结果:用V替换主串S中出现的所有与T相等的不重叠的子串。
StrInsert (&S, pos, T)
	初始条件:串S和T存在, 1≤pos≤StrLength(S)+1。
	操作结果:在串S的第pos个字符之前插入串T。
StrDelete (&S, pos, len)
	初始条件:串S存在, 1≤pos≤StrLength(S)-len+1。
	操作结果:从串S中删除第pos个字符起长度为len的子串。
DestroyString (&S)
	初始条件:串S存在。
	操作结果:串S被销毁。

endADT

串的基本运算

对于串的基本操作,与线性表还是很有差别的,线性表关注的是单个元素的操作,比如查找一个元素,插入或是删除一个元素,但串中更多的是查找子串的位置、得到指定位置子串、替换子串等操作。

求串长:StrLength(s);
串赋值:StrAssign(s1,s2);    // 将s2的串值赋予s1
连接运算:StrConcat(s1,s2,s) 或 StrConcat(s1,s2).//在s1后面连接s2的串值,产生新串s
求子串:SubStr(s,i,len);//返回s的第i至len个字符的子串值。len=0为空串。例如:SubStr("abcdefg",2,3) = "bcd"
串比较:StrComp(s1,s2);//若s1 =s2 ,操作返回值为0;s1<s2,返回值<0;反之>0
串定位:StrIndex(s,t);//若t被包含于s中,则返回值为t的位置,反之值为-1
串插入:StrInsert(s,i,t);//将串t插入到s的第i个字符位置上
串删除:StrDelete(s,i,len);//删除串t中第i至len个字符的子串
串修改:StrRep(s,t,r);//用串r替换s中出现的所有与串t相等且不重叠的子串

串的表示方法

串有3种机内的表示方法

1.定长顺序存储表示

类似于线性表中的顺序存储结构,是用一组地址连续的存储单元来存储串中的字符序列的。按照预定义的大小,为每个定义的串变量分配一个固定长度的存储区。

串连接:把两个串s1和s2首尾连接成一个新串s,即s<-s1+s2

int StrConcat(s1,s2,s)
    char s1[],s2[],s[];//将串s1,s2合并到串s,合并成功返回1,否则返回0
{
    int i =0,j,len1,len2;
    len1 = StrLength(s1);
    len2 = StrLength(s2);
    
    if(len1+len2>MAXSIZE-1) return 0;    //s 长度不够
 
    j = 0 ;
    while(s1[j]! ="\0"){
        s[i] = s1[j];
        i++;
        j++;
    }
     while(s2[j]! ="\0"){
        s[i] = s2[j];
        i++;
        j++;
    }
    s[i] = "\0";
    return 1;
}

 求子串:

int StrSub(char *t ,char *s,int i , in len){
//用t返回串s中第i个字符串开始的长度为len的子串,1<=i串长
    
    int slen;
    slen = StrLength(s);
    if(i<1 || i>slen || len<0 || len>slen-i+1){
        return 0;
    }
    
    for(j =0 ; j<len ; j++){
        t[j] =s[i+j-1];
        t[j] ="\0";
        return 1;
    }
}

2.堆分配存储表示

在顺序串上的插入、删除操作并不方便,必须移动大量的字符,而且当操作中出现串值序列的长度超过上界MAXSIZE时,只能用截尾法处理。要克服这个弊病,只有不限定串的最大长度,动态分配串值的存储空间。

堆分配存储结构的特点是:仍以一组地址连续的存储单元存放串的字符序列,但其存储空间是在算法执行过程中动态分配得到的。在C语言中,由动态分配函数malloc()和free()来管理。利用函数malloc()为每一个新产生的串分配一块实际需要的存储空间,若分配成功,则返回一个指针,指向串的起始地址。

由于堆分配存储结构的串既有顺序存储结构的特点,在操作中又没有串长的限制,显得很灵活,因此,在串处理的应用程序中常被选用。

3.串的块链存储表示

串的链式存储与线性表相似,但由于串结构的特殊性,结构中的每个元素数据都是一个字符,如果也简单的应用链表存储串值,一个结点对应一个字符,就会存在很大的空间浪费,因此一个结点可以存放多个字符,最后一个结点若是未被占满时,可以用 "#" 或其它非串值字符补全。

为了便于进行串的操作,当以链表存储串值时,除头指针外还可附设一个尾指针指示链表中的最后一个结点,并给出当前串的长度。称如此定义的串存储结构为块链结构。

猜你喜欢

转载自blog.csdn.net/suxiaorui/article/details/101100977