SlideShare a Scribd company logo
1 of 42
第四章    串
 4.1 串类型的定
 义
4.2 串的表示和实现
学习提要:
 1. 熟悉串的基本操作的定义,并能利用这
些
基本操作来实现串的其它各种操作的方法
。
 2. 熟练掌握在串的定长顺序存储结构上实
现串的各种操作的方法。
 3. 掌握串的堆分配存储结构以及在其上实
现串操作的基本方法。
4. 了解串的块链存储结构。
重难点内容:
 串的存储结构
§4.1 串类型的定义
基本概念

串( string ):由零个或多个字
符组成的有限序列,也称字符串。
记为:
    S = ‘a1a2a3……an’ (n≥0)

         如: A= ‘BEIJING’ ,   B=
‘JING’
空串:不含任何字符的串,串长度为
0,
         用“    ” 或 ‘ ’ 表示。
空格串:仅由一个或多个空格组成的
串,
          长度为串中空格字符的
个数。
  如: ‘   ’ ,    C= ‘ BEI JING ’
子串:由串中任意个连续的字符组成
的
字符在串中的位置:字符在序列中的
序号。
子串在主串中的位置:以子串的第一
个字符在主串中的位置来表示。
 如: A= ‘ BEIJING ’ , B= ‘JING ’ ,
   B 在 A 中的位置为 4 。
 串相等:当且仅当两个串的值相等。
也就是说,只有两个串的长度相等且各
个对应位置的字符都相等时才相等。
串的抽象数据类型定义
ADT String {
    数据对象:
  D = { ai |ai∈ CharacterSet,
       i=1,2,...,n, n≥0 }
    数据关系:
  R1 = { < ai-1, ai > | ai-1, ai ∈ D,
         i=2,...,n }
    基本操作:
    ……
} ADT String
StrAssign (&T, chars) // 串赋值
    初始条件: chars 是字符串常量。
    操作结果:把 chars 赋为 T 的值。
StrCopy (&T, S) // 串复制
     初始条件:串 S 存在。
     操作结果:由串 S 复制得串 T 。
DestroyString (&S)
     初始条件:串 S 存在。
     操作结果:串 S 被销毁。
ClearString (&S)
    初始条件:串 S 存在。
   操作结果:将 S 清为空串。
StrEmpty (S)
    初始条件:串 S 存在。
      操作结果:若 S 为空串,则返回
 TRUE ,否则返回 FALSE 。
StrCompare (S, T) // 串比较
 初始条件:串 S 和 T 存在。
 操作结果:若 S>T ,则返回值 >0 ;
           若 S=T ,则返回值 =0 ;
           若 S<T ,则返回值 <0 。

  StrCompare(‘data’, ‘structure’) <0
字符串的比较规则 : 对两个字符串自左至右逐
个字符相比 ( 按 ASCII 码值大小 ), 直到出现不
同字符或遇到结束符为止 . 如全部字符相同则
认为相等 ; 若出现不相同的字符 , 则以第一个
不相同的字符的比较结果为准 , 如上
例 “ d”<“s”. 因此比较结果小于 0 。
StrLength (S) // 求串长
 初始条件:串 S 存在。
   操作结果:返回 S 的元素个数
,称为串的长度。
Concat (&T, S1, S2) // 串联接
 初始条件:串 S1 和 S2 存在。
  操作结果:用 T 返回由 S1 和 S2
 联接而成的新串。
 Concat(&T,‘data’, ‘structure’)

    T=‘datastructure’
SubString (&Sub, S, pos, len) // 求子串
                      初始条件:串 S 存
 在, 1≤pos≤StrLength(S) 且
 0≤len≤StrLength(S)-pos+1 。
 操作结果:用 Sub 返回串 S 的第 pos 个
 字符起长度为 len 的子串。
SubString(&sub, ‘data structure’, 6, 9)

         Sub=‘structure’
Index (S, T, pos) // 串定位
   初始条件:串 S 和 T 存在, T 是非空串,
           1≤pos≤StrLength(S) 。
   操作结果:若主串 S 中存在和串 T 值相同
 的子串 , 则返回它在主串 S 中第 pos 个字符之
 后第一次出现的位置 ; 否则函数值为 0 。
假设: S = ′abcaabcaaabc′, T = ′bca′
       Index(S, T, 1) = 2 ;
       Index(S, T, 3) = 6 ;
       Index(S, T, 8) = 0 ;
Replace (&S, T, V) // 串替换
 初始条件:串 S,T 和 V 存在, T 是非
空串。
  操作结果:用 V 替换主串 S 中出现
的所有与 T 相等的不重叠的子串。
例如: S=‘abcaabc’, T=‘ab’, V=‘x’
      S=‘xcaxc’
      V=‘bc’
      S=‘bccabcc’
StrInsert (&S, pos, T)
 初始条件:串 S 和 T 存在,
       1≤pos≤StrLength(S) + 1 。
  操作结果:在串 S 的第 pos 个字符之
 前插
例如: S =‘ god’ , T 。
               入串 StrInsert ( & S,
2, ‘o’)
          S=‘good’
StrDelete (&S, pos, len)
  初始条件:串 S 存在,
      1≤pos≤StrLength(S)-len+1 。
   操作结果:从串 S 中删除第 pos 个字符
 起
              长度为 len 的子串。
 例如 : S= ‘structure’ ,
         StrDelete( & S, 1, 5)
         S=‘ture’
对于串的基本操作集可以有不同的
 定义方法,在使用高级程序设计语言中的
 串类型时,应以该语言的参考手册为准。
例如: C 语言函数库中提供下列串处理函数:
                       K 的作用是将 s tr2 中前
 gets(str) 输入一个串;      k 个字符复制到 s rt1 中
 puts(str) 输出一个串;      去,取代 s tr1 中最前面
                       k 个字符。
 strcat(str1, str2) 串联接函数;
 strcpy(str1, str2, k) 串复制函数;
 strcmp(str1, str2) 串比较函数;
 strlen(str) 求串长函数;
在以上操作中,
串赋值 StrAssign 、串复制 Strcopy 、
串比较 StrCompare 、求串长
StrLength 、串联接 Concat 、求子串
SubString
6 种操作构成串类型的最小操作子集,
即:这些操作不可能利用其他串操作来
实现,反之,其他串操作(除串清除
ClearString 和串销毁 DestroyString 外)
可在这个最小操作子集上实现。
例如,可利用串比较、求串长和求子
串 等操作实现定位函数 Index(S, T,
pos) 。
 算法的基本思想为
 :
StrCompare(SubString(S, i, StrLength(T)), T) = = 0
            i
                      S 串
      pos       T 串                n-m+1 T 串
    在主串 S 中取出从第 i 个字符起,长度和串 T 相等的子串和串 T
进行比较,若相等,则求得函数值为 i ;否则 i 值增 1 直至串 S 中不存在
和串 T 相等的子串为止。
int Index (String S, String T, int pos) {
// T 为非空串。若主串 S 中第 pos 个字符之后存在与 T 相等的子
则返回第一个这样的子串在 S 中的位置,否则返回 0
 if (pos > 0) {
   n = StrLength(S); m = StrLength(T); i = pos;
   while ( i <= n-m+1) {
      SubString (sub, S, i, m); // 从 S 中取子串置于 sub 中
      if (StrCompare(sub,T) != 0) ++i ;
      else return i ;
   } // while
 } // if
 return 0;        // S 中不存在与 T 相等的子串
} // Index
C++ 中的 String 类
   C++ 标准类库将面向对象串的概念加入到 C+
 + 语言中。串类封装了类的属性,并提供了一
 系列允许访问这些属性的服务。例如: String
 类的一些主要的成员函数有:
string append(const char *s); // 将字符串 s 加在本串尾
string assign(const char *s); // 赋值
Int compare(const string& str); // 比较本串与 str 中串的大小
 string insert(int p0, const *s);
                 // 将 s 所指向的字符串插入本串位置 p0 之
前
串的逻辑结构和线性表极为相
似,区别仅在于串的数据对象约束为
字符集。
 串的基本操作和线性表有很大差
别。
  在线性表的基本操作中,大多以“
单个元素 ” 作为操作对象;
  在串的基本操作中,通常以“ 串的
整体 ” 作为操作对象。
§4.2 串的表示和实现
4.2.1 串的定长顺序存储表示

4.2.2 串的堆分配存储表示

4.2.3 串的块链存储表示
4.2.1 定长顺序存储表示
   用一组地址连续的存储单元存储串
值的字符序列,类似于线性表的顺序存储
结构。所谓定长顺序存储结构,是直接使
用定长的字符数组来定义,数组的上界预
先给出:
 #define MAXSTRLEN 255
              // 用户可在 255 以内定义最大串
 长
 typedef unsigned char
         SString[MAXSTRLEN + 1];
特点 :
串的实际长度可在这个予定义长
度的范围内随意设定,超过予定义
长度的串值则被舍去,称之为“ 截
断” 。
按这种串的表示方法实现的串的
运算时,其基本操作为 “ 字符序列
的复制 ” 。
1 .串联结
Contcat ( &T,S1,S2 )

        S1 [ 0           S2 [ 0
          ]                ]
S1                 S2


T


                 T[0]             MAXSTRLEN


     S1[0]+S2[0] <= MAXSTRLEN
S1 [ 0           S2 [ 0
              ]                ]
    S1                 S2


                                 S2 中被截去的
    T                               字符序列


               T[0]     MAXSTRLEN



S1[0] < MAXSTRSIZE 而 S1[0]+S2[0] > MAXSTRSIZE
S1 [ 0               S2 [ 0
         ]                    ]
S1                  S2


T
                                S2 串被全部截
                                    去
     T[0]       MAXSTRLEN



     S1[0] = MAXSTRLEN
Status Concat(SString S1, SString S2, SString &T) {
  if (S1[0]+S2[0] <= MAXSTRLEN) { // 未截断
        T[1..S1[0]] = S1[1…S1[0]];
        T[S1[0]+1…S1[0]+S2[0]] = S2[1…S2[0]];
        T[0] = S1[0]+S2[0]; uncut = TRUE;}
  else if (S1[0] < MAXSTRSIZE) {           // 截断
        T[1…S1[0]] = S1[1…S1[0]];
        T[S1[0]+1…MAXSTRLEN]=S2[1…MAXSTRLEN - S1[0]];
         T[0] = MAXSTRLEN; uncut = FALSE;}
         else { S1[0] = MAXSTRSIZE // 截断 ( 仅取 S1)
            T[0...MAXSTRLEN] = S1[0…MAXSTRLEN];
                           // T[0] == S1[0] == MAXSTRLEN
          uncut = FALSE; }
 return uncut;
} // Concat
2 .求子串 SubString(&Sub, S, pos, len)

Status SubString(SString&Sub, SString S, int
pos,int len) {
// 用 Sub 返回串 S 的第 pos 个字符起长度为 len 的子串。其
中       1≤pos ≤StrLength(S) 且 0≤len≤StrLength(S)-pos+1
  if (pos<1 ||pos>S[0] || len<0 || len>S[0]-pos+1)
       return ERROR;
  Sub[1……len]=S[pos…pos+len-1] ;
  Sub[0]=len ;
  return OK;
} // SubString
定长顺序存储表示的特点与问题
1 . 实现串操作的原操作为“ 字符序列的复制” ,操
作的时间复杂度基于复制的字符序列的长度。
2. 在操作中出现串值序列的长度超过 MaxS trLe n
时,约定用截尾法处理,这种情况可能在联结串
或插入 , 置换时发生。
3. 克服这个问题惟有不限定串长的最大长度,即
动态分配串值的存储空间。
4.2.2 堆分配存储表示
   以一组地址连续的存储单元存储串值的字符序
列,存储空间在程序执行过程中动态分配。
   C 语言中提供的串类型就是以这种存储方式实
现的。系统利用函数 m allo c () 和 fre e ( ) 进行串值空
间的动态管理,为每一个新产生的串分配一个存储
区,称串值共享的存储空间为“ 堆”。
   C 语言中的串以一个空字符为结束符,串长是
一个隐含值。
typedef struct {
   char *ch; // 若是非空串,则按串长分
                          配存储区 , 否则
ch 为 NULL
   int length;   // 串长度
} HString;
这类串操作实现的算法为:
  先为新生成的串分配一个存储空间,然后进行
串值的复制。
1. 串赋值
Status StrAssign(Hstring&T,char*chars){
// 生成一个其值等于串常量 chars 的串 T
    If ( T.ch ) free (T.ch); // 释放 T 原有空间
    for(i=0,c=chars; c; ++i,++c); // 求 chars 的长度
i
    If ( !i ) {T.ch=NULL; T.length=0;}
    else{
        if(!(T.ch=(char*)malloc(i*sizeof(char))))
            exit(OVERFLOW); // 开辟空间再赋值
        T.ch[0…i-1]=chars[0…i-1]; T.length=i; }
    return OK;
2. 串比较 ;
Int StrCompare(Hstring S,Hstring T){
  for(i=0; i<S.length && i<T.length; ++i)
    if ( S.ch[i] != T.ch[i] )
            Return S.ch[i]-T.ch[i];
 Return S.length - T.length
    // 若 S>T, 则返回值 >0; 若 S=T, 则返回值 =0 ;
        若 S<T ,则返回值 =0
}   // StrCompare
3. 串联接
Status Concat(Hstring&T,HStringS1,HstringS2)
{ // 用 T 返回由 S1 和 S2 联接而成的新串
if(T.ch) free(T.ch); // 释放旧空间
if(!(T.ch=(char*)malloc((S1.length+S2.length)*
sizeof(char)))) exit(OVERFLOW);
T.ch[0…S1.length - 1]= S1.ch[0…S1.length - 1];
T.length= S1.length+ S2.length;
T.ch[S1.length…T.length-1]=S2.ch[0…S2.length-1];
return OK;
} // Concat
4. 取子串
Status SubString(HString&Sub,Hstring S,int pos,int len)
{ // 用 Sub 返回串 S 的第 pos 个字符起长度为 len 的子串。
// 其中 1≤pos StrLength(S) 且 0≤ len≤ StrLength(S)-pos+1
if (pos<1 ||pos>S.length || len<0||len>S.length-pos+1)
   return ERROR;
if(Sub.ch) free(Sub.ch); // 释放旧空间
if (!len){ Sub.ch=NULL; Sub.length=0; } // 空子串
else { // 完整子串
   Sub.ch= (char*) malloc (len*sizeof(char));
                                     // 取长度 len 分配空
间
   Sub.ch[0…len-1]=S.ch[pos-1…pos+len-2] ;
   Sub.length=len ;
return OK;
4.2.3 块链存储表示
   以链表存储串值,除头指针外还可
以附设一个尾指针指示链表中的最后一
个结点,并给出当前串的长度。称如此
定义的串存储结构为 块链结构。 结点大小
          块链结构
#define CHUNKSIZE 80 // 可由用户定义的块大小
typedef struct Chunk { // 结点结构
  char ch[CUNKSIZE];
  struct Chunk *next;
 } Chunk;
typedef struct { // 串的链表结构
  Chunk *head, *tail; // 串的头和尾指针
   int curlen; // 串的当前长度
 } LString;
例如 : 在编辑系统中,整个文本编辑区可
以看成是一个串,每一行是一个子串,构
成一个结点。即 : 同一行的串用定长结构
(80 个字符 ), 行和行之间用指针相联接。


       数据元素所占存储位
存储密度 = 实际分配的存储位
存储密度的大小直接影响着串处理的效
  率.
1. 存储密度小 , 运算处理方便 , 但存储占用
  量大 .
2. 存储密度小 , 在串处理过程中需要进行内
  外存交换的话 , 会因为内外存交换操作过
  多而影响处理的总效率 .
   串值的链式存储结构对于某些串操作
有一定方便处 , 但总的说来不如另外两种存
储结构灵活 , 它占用存储量大且操作复杂 .
练习 : 设 s=‘I AM A
STUDENT’ , t=‘GOOD’ ,
q=‘WORKER’ ,求:
( 1 ) StrLength(s) , StrLength(t)
( 2 ) SubString(s, 8, 7) , SubString(t, 2, 1)
( 3 ) Index(s, ‘A’,1) , Index(s,t,3)
( 4 ) Replace(s, ‘STUDENT’, q)
( 5)
Concat(SubString(s,6,2),Concat(t,SubString(s,7,8)))

More Related Content

Viewers also liked

презентация
презентацияпрезентация
презентацияromagrave
 
Escrita semplagio final
Escrita semplagio finalEscrita semplagio final
Escrita semplagio finalclaudia murta
 
melssCRM brochure
melssCRM brochuremelssCRM brochure
melssCRM brochuremorrisraja
 
2011 08-14 - mudar o mundo
2011 08-14 - mudar o mundo2011 08-14 - mudar o mundo
2011 08-14 - mudar o mundoO Ciclista
 
2011 06-14 - diário inês castro
2011 06-14 - diário inês castro2011 06-14 - diário inês castro
2011 06-14 - diário inês castroO Ciclista
 
Metodologia pesquisa
Metodologia pesquisaMetodologia pesquisa
Metodologia pesquisaclaudia murta
 
C4 web
C4 webC4 web
C4 webMami f
 
2014 09-11 - o menino com guelras
2014 09-11 - o menino com guelras2014 09-11 - o menino com guelras
2014 09-11 - o menino com guelrasO Ciclista
 
Kaip elgtis prieš tv kameras
Kaip elgtis prieš tv kamerasKaip elgtis prieš tv kameras
Kaip elgtis prieš tv kamerasJurga Chomskyte
 
เรื่อง ทรัพย์สินทางปัญญา
เรื่อง ทรัพย์สินทางปัญญาเรื่อง ทรัพย์สินทางปัญญา
เรื่อง ทรัพย์สินทางปัญญาFUEANG Far
 
2012 05-01 - receitas - ana rita lucas 8 c
2012 05-01 - receitas  - ana rita lucas 8 c2012 05-01 - receitas  - ana rita lucas 8 c
2012 05-01 - receitas - ana rita lucas 8 cO Ciclista
 
Aula 01 desenho tecnico- cetep
Aula 01  desenho tecnico- cetepAula 01  desenho tecnico- cetep
Aula 01 desenho tecnico- cetepMargarete Santana
 
2015 01-02 - exposição temporária
2015 01-02 - exposição temporária2015 01-02 - exposição temporária
2015 01-02 - exposição temporáriaO Ciclista
 
2012 04-20 - receita ana rita gomes
2012 04-20 - receita ana rita gomes2012 04-20 - receita ana rita gomes
2012 04-20 - receita ana rita gomesO Ciclista
 

Viewers also liked (20)

Feliz natal
Feliz natalFeliz natal
Feliz natal
 
презентация
презентацияпрезентация
презентация
 
Escrita semplagio final
Escrita semplagio finalEscrita semplagio final
Escrita semplagio final
 
melssCRM brochure
melssCRM brochuremelssCRM brochure
melssCRM brochure
 
Cyn
CynCyn
Cyn
 
Figuras linguagem
Figuras linguagemFiguras linguagem
Figuras linguagem
 
2011 08-14 - mudar o mundo
2011 08-14 - mudar o mundo2011 08-14 - mudar o mundo
2011 08-14 - mudar o mundo
 
2011 06-14 - diário inês castro
2011 06-14 - diário inês castro2011 06-14 - diário inês castro
2011 06-14 - diário inês castro
 
Metodologia pesquisa
Metodologia pesquisaMetodologia pesquisa
Metodologia pesquisa
 
C4 web
C4 webC4 web
C4 web
 
1er Trabajo
1er Trabajo1er Trabajo
1er Trabajo
 
Pio.La Periodistas Redes Sociales
Pio.La Periodistas Redes SocialesPio.La Periodistas Redes Sociales
Pio.La Periodistas Redes Sociales
 
2014 09-11 - o menino com guelras
2014 09-11 - o menino com guelras2014 09-11 - o menino com guelras
2014 09-11 - o menino com guelras
 
Kaip elgtis prieš tv kameras
Kaip elgtis prieš tv kamerasKaip elgtis prieš tv kameras
Kaip elgtis prieš tv kameras
 
เรื่อง ทรัพย์สินทางปัญญา
เรื่อง ทรัพย์สินทางปัญญาเรื่อง ทรัพย์สินทางปัญญา
เรื่อง ทรัพย์สินทางปัญญา
 
2012 05-01 - receitas - ana rita lucas 8 c
2012 05-01 - receitas  - ana rita lucas 8 c2012 05-01 - receitas  - ana rita lucas 8 c
2012 05-01 - receitas - ana rita lucas 8 c
 
Trabajo Luis
Trabajo LuisTrabajo Luis
Trabajo Luis
 
Aula 01 desenho tecnico- cetep
Aula 01  desenho tecnico- cetepAula 01  desenho tecnico- cetep
Aula 01 desenho tecnico- cetep
 
2015 01-02 - exposição temporária
2015 01-02 - exposição temporária2015 01-02 - exposição temporária
2015 01-02 - exposição temporária
 
2012 04-20 - receita ana rita gomes
2012 04-20 - receita ana rita gomes2012 04-20 - receita ana rita gomes
2012 04-20 - receita ana rita gomes
 

Similar to 第四章 串

自然语言处理 中文分词程序实验报告%28含源代码%29
自然语言处理 中文分词程序实验报告%28含源代码%29自然语言处理 中文分词程序实验报告%28含源代码%29
自然语言处理 中文分词程序实验报告%28含源代码%29aemoe
 
第三章 栈和队列
第三章 栈和队列第三章 栈和队列
第三章 栈和队列Wang Yizhe
 
第三章 栈和队列(新)
第三章 栈和队列(新)第三章 栈和队列(新)
第三章 栈和队列(新)Wang Yizhe
 
Standford 2015 iOS讀書會 week2: 1. Applying MVC 2. More Swift and Foundation Fra...
Standford 2015 iOS讀書會 week2: 1. Applying MVC 2. More Swift and Foundation Fra...Standford 2015 iOS讀書會 week2: 1. Applying MVC 2. More Swift and Foundation Fra...
Standford 2015 iOS讀書會 week2: 1. Applying MVC 2. More Swift and Foundation Fra...彼得潘 Pan
 
第5章 自底向上的语法分析
第5章 自底向上的语法分析第5章 自底向上的语法分析
第5章 自底向上的语法分析tjpucompiler
 
博大正方C语言试题V2.0
博大正方C语言试题V2.0博大正方C语言试题V2.0
博大正方C语言试题V2.0yiditushe
 
07 陣列與字串
07 陣列與字串07 陣列與字串
07 陣列與字串shademoon
 
JCConf 2023 - 深入淺出 Java 21 功能
JCConf 2023 - 深入淺出 Java 21 功能JCConf 2023 - 深入淺出 Java 21 功能
JCConf 2023 - 深入淺出 Java 21 功能Joseph Kuo
 
Python learn guide
Python learn guidePython learn guide
Python learn guiderobin yang
 

Similar to 第四章 串 (12)

自然语言处理 中文分词程序实验报告%28含源代码%29
自然语言处理 中文分词程序实验报告%28含源代码%29自然语言处理 中文分词程序实验报告%28含源代码%29
自然语言处理 中文分词程序实验报告%28含源代码%29
 
第三章 栈和队列
第三章 栈和队列第三章 栈和队列
第三章 栈和队列
 
第三章 栈和队列(新)
第三章 栈和队列(新)第三章 栈和队列(新)
第三章 栈和队列(新)
 
Standford 2015 iOS讀書會 week2: 1. Applying MVC 2. More Swift and Foundation Fra...
Standford 2015 iOS讀書會 week2: 1. Applying MVC 2. More Swift and Foundation Fra...Standford 2015 iOS讀書會 week2: 1. Applying MVC 2. More Swift and Foundation Fra...
Standford 2015 iOS讀書會 week2: 1. Applying MVC 2. More Swift and Foundation Fra...
 
2
22
2
 
第5章 自底向上的语法分析
第5章 自底向上的语法分析第5章 自底向上的语法分析
第5章 自底向上的语法分析
 
博大正方C语言试题V2.0
博大正方C语言试题V2.0博大正方C语言试题V2.0
博大正方C语言试题V2.0
 
SCJP ch10
SCJP ch10SCJP ch10
SCJP ch10
 
Xml基础培训
Xml基础培训Xml基础培训
Xml基础培训
 
07 陣列與字串
07 陣列與字串07 陣列與字串
07 陣列與字串
 
JCConf 2023 - 深入淺出 Java 21 功能
JCConf 2023 - 深入淺出 Java 21 功能JCConf 2023 - 深入淺出 Java 21 功能
JCConf 2023 - 深入淺出 Java 21 功能
 
Python learn guide
Python learn guidePython learn guide
Python learn guide
 

More from Wang Yizhe

第六章 树和二叉树2
第六章 树和二叉树2第六章 树和二叉树2
第六章 树和二叉树2Wang Yizhe
 
第九章+查找[4]
第九章+查找[4]第九章+查找[4]
第九章+查找[4]Wang Yizhe
 
第九章 查找[3]
第九章 查找[3]第九章 查找[3]
第九章 查找[3]Wang Yizhe
 
第九章 查找[2]
第九章 查找[2]第九章 查找[2]
第九章 查找[2]Wang Yizhe
 
第九章 查找[1]
第九章 查找[1]第九章 查找[1]
第九章 查找[1]Wang Yizhe
 
第七章 图[4]1
第七章 图[4]1第七章 图[4]1
第七章 图[4]1Wang Yizhe
 
第七章 图[3]
第七章 图[3]第七章 图[3]
第七章 图[3]Wang Yizhe
 
第七章 图[2]1
第七章 图[2]1第七章 图[2]1
第七章 图[2]1Wang Yizhe
 
第七章 图[1]
第七章 图[1]第七章 图[1]
第七章 图[1]Wang Yizhe
 
数据结构 总结与复习
数据结构 总结与复习数据结构 总结与复习
数据结构 总结与复习Wang Yizhe
 
第四章 串操作应用举例
第四章 串操作应用举例第四章 串操作应用举例
第四章 串操作应用举例Wang Yizhe
 
第二章 线性表
第二章 线性表第二章 线性表
第二章 线性表Wang Yizhe
 

More from Wang Yizhe (13)

第六章 树和二叉树2
第六章 树和二叉树2第六章 树和二叉树2
第六章 树和二叉树2
 
第六章1
第六章1第六章1
第六章1
 
第九章+查找[4]
第九章+查找[4]第九章+查找[4]
第九章+查找[4]
 
第九章 查找[3]
第九章 查找[3]第九章 查找[3]
第九章 查找[3]
 
第九章 查找[2]
第九章 查找[2]第九章 查找[2]
第九章 查找[2]
 
第九章 查找[1]
第九章 查找[1]第九章 查找[1]
第九章 查找[1]
 
第七章 图[4]1
第七章 图[4]1第七章 图[4]1
第七章 图[4]1
 
第七章 图[3]
第七章 图[3]第七章 图[3]
第七章 图[3]
 
第七章 图[2]1
第七章 图[2]1第七章 图[2]1
第七章 图[2]1
 
第七章 图[1]
第七章 图[1]第七章 图[1]
第七章 图[1]
 
数据结构 总结与复习
数据结构 总结与复习数据结构 总结与复习
数据结构 总结与复习
 
第四章 串操作应用举例
第四章 串操作应用举例第四章 串操作应用举例
第四章 串操作应用举例
 
第二章 线性表
第二章 线性表第二章 线性表
第二章 线性表
 

第四章 串

  • 1. 第四章 串 4.1 串类型的定 义 4.2 串的表示和实现
  • 2. 学习提要: 1. 熟悉串的基本操作的定义,并能利用这 些 基本操作来实现串的其它各种操作的方法 。 2. 熟练掌握在串的定长顺序存储结构上实 现串的各种操作的方法。 3. 掌握串的堆分配存储结构以及在其上实 现串操作的基本方法。 4. 了解串的块链存储结构。 重难点内容: 串的存储结构
  • 3. §4.1 串类型的定义 基本概念 串( string ):由零个或多个字 符组成的有限序列,也称字符串。 记为: S = ‘a1a2a3……an’ (n≥0) 如: A= ‘BEIJING’ , B= ‘JING’
  • 4. 空串:不含任何字符的串,串长度为 0, 用“ ” 或 ‘ ’ 表示。 空格串:仅由一个或多个空格组成的 串, 长度为串中空格字符的 个数。 如: ‘ ’ , C= ‘ BEI JING ’ 子串:由串中任意个连续的字符组成 的
  • 5. 字符在串中的位置:字符在序列中的 序号。 子串在主串中的位置:以子串的第一 个字符在主串中的位置来表示。 如: A= ‘ BEIJING ’ , B= ‘JING ’ , B 在 A 中的位置为 4 。  串相等:当且仅当两个串的值相等。 也就是说,只有两个串的长度相等且各 个对应位置的字符都相等时才相等。
  • 6. 串的抽象数据类型定义 ADT String { 数据对象: D = { ai |ai∈ CharacterSet, i=1,2,...,n, n≥0 } 数据关系: R1 = { < ai-1, ai > | ai-1, ai ∈ D, i=2,...,n } 基本操作: …… } ADT String
  • 7. StrAssign (&T, chars) // 串赋值 初始条件: chars 是字符串常量。 操作结果:把 chars 赋为 T 的值。 StrCopy (&T, S) // 串复制 初始条件:串 S 存在。 操作结果:由串 S 复制得串 T 。 DestroyString (&S) 初始条件:串 S 存在。 操作结果:串 S 被销毁。
  • 8. ClearString (&S) 初始条件:串 S 存在。 操作结果:将 S 清为空串。 StrEmpty (S) 初始条件:串 S 存在。 操作结果:若 S 为空串,则返回 TRUE ,否则返回 FALSE 。
  • 9. StrCompare (S, T) // 串比较 初始条件:串 S 和 T 存在。 操作结果:若 S>T ,则返回值 >0 ; 若 S=T ,则返回值 =0 ; 若 S<T ,则返回值 <0 。 StrCompare(‘data’, ‘structure’) <0 字符串的比较规则 : 对两个字符串自左至右逐 个字符相比 ( 按 ASCII 码值大小 ), 直到出现不 同字符或遇到结束符为止 . 如全部字符相同则 认为相等 ; 若出现不相同的字符 , 则以第一个 不相同的字符的比较结果为准 , 如上 例 “ d”<“s”. 因此比较结果小于 0 。
  • 10. StrLength (S) // 求串长 初始条件:串 S 存在。 操作结果:返回 S 的元素个数 ,称为串的长度。
  • 11. Concat (&T, S1, S2) // 串联接 初始条件:串 S1 和 S2 存在。 操作结果:用 T 返回由 S1 和 S2 联接而成的新串。 Concat(&T,‘data’, ‘structure’) T=‘datastructure’
  • 12. SubString (&Sub, S, pos, len) // 求子串 初始条件:串 S 存 在, 1≤pos≤StrLength(S) 且 0≤len≤StrLength(S)-pos+1 。 操作结果:用 Sub 返回串 S 的第 pos 个 字符起长度为 len 的子串。 SubString(&sub, ‘data structure’, 6, 9) Sub=‘structure’
  • 13. Index (S, T, pos) // 串定位 初始条件:串 S 和 T 存在, T 是非空串, 1≤pos≤StrLength(S) 。 操作结果:若主串 S 中存在和串 T 值相同 的子串 , 则返回它在主串 S 中第 pos 个字符之 后第一次出现的位置 ; 否则函数值为 0 。 假设: S = ′abcaabcaaabc′, T = ′bca′ Index(S, T, 1) = 2 ; Index(S, T, 3) = 6 ; Index(S, T, 8) = 0 ;
  • 14. Replace (&S, T, V) // 串替换 初始条件:串 S,T 和 V 存在, T 是非 空串。 操作结果:用 V 替换主串 S 中出现 的所有与 T 相等的不重叠的子串。 例如: S=‘abcaabc’, T=‘ab’, V=‘x’ S=‘xcaxc’ V=‘bc’ S=‘bccabcc’
  • 15. StrInsert (&S, pos, T) 初始条件:串 S 和 T 存在, 1≤pos≤StrLength(S) + 1 。 操作结果:在串 S 的第 pos 个字符之 前插 例如: S =‘ god’ , T 。 入串 StrInsert ( & S, 2, ‘o’) S=‘good’
  • 16. StrDelete (&S, pos, len) 初始条件:串 S 存在, 1≤pos≤StrLength(S)-len+1 。 操作结果:从串 S 中删除第 pos 个字符 起 长度为 len 的子串。 例如 : S= ‘structure’ , StrDelete( & S, 1, 5) S=‘ture’
  • 17. 对于串的基本操作集可以有不同的 定义方法,在使用高级程序设计语言中的 串类型时,应以该语言的参考手册为准。 例如: C 语言函数库中提供下列串处理函数: K 的作用是将 s tr2 中前 gets(str) 输入一个串; k 个字符复制到 s rt1 中 puts(str) 输出一个串; 去,取代 s tr1 中最前面 k 个字符。 strcat(str1, str2) 串联接函数; strcpy(str1, str2, k) 串复制函数; strcmp(str1, str2) 串比较函数; strlen(str) 求串长函数;
  • 18. 在以上操作中, 串赋值 StrAssign 、串复制 Strcopy 、 串比较 StrCompare 、求串长 StrLength 、串联接 Concat 、求子串 SubString 6 种操作构成串类型的最小操作子集, 即:这些操作不可能利用其他串操作来 实现,反之,其他串操作(除串清除 ClearString 和串销毁 DestroyString 外) 可在这个最小操作子集上实现。
  • 19. 例如,可利用串比较、求串长和求子 串 等操作实现定位函数 Index(S, T, pos) 。 算法的基本思想为 : StrCompare(SubString(S, i, StrLength(T)), T) = = 0 i S 串 pos T 串 n-m+1 T 串 在主串 S 中取出从第 i 个字符起,长度和串 T 相等的子串和串 T 进行比较,若相等,则求得函数值为 i ;否则 i 值增 1 直至串 S 中不存在 和串 T 相等的子串为止。
  • 20. int Index (String S, String T, int pos) { // T 为非空串。若主串 S 中第 pos 个字符之后存在与 T 相等的子 则返回第一个这样的子串在 S 中的位置,否则返回 0 if (pos > 0) { n = StrLength(S); m = StrLength(T); i = pos; while ( i <= n-m+1) { SubString (sub, S, i, m); // 从 S 中取子串置于 sub 中 if (StrCompare(sub,T) != 0) ++i ; else return i ; } // while } // if return 0; // S 中不存在与 T 相等的子串 } // Index
  • 21. C++ 中的 String 类 C++ 标准类库将面向对象串的概念加入到 C+ + 语言中。串类封装了类的属性,并提供了一 系列允许访问这些属性的服务。例如: String 类的一些主要的成员函数有: string append(const char *s); // 将字符串 s 加在本串尾 string assign(const char *s); // 赋值 Int compare(const string& str); // 比较本串与 str 中串的大小 string insert(int p0, const *s); // 将 s 所指向的字符串插入本串位置 p0 之 前
  • 22. 串的逻辑结构和线性表极为相 似,区别仅在于串的数据对象约束为 字符集。 串的基本操作和线性表有很大差 别。 在线性表的基本操作中,大多以“ 单个元素 ” 作为操作对象; 在串的基本操作中,通常以“ 串的 整体 ” 作为操作对象。
  • 23. §4.2 串的表示和实现 4.2.1 串的定长顺序存储表示 4.2.2 串的堆分配存储表示 4.2.3 串的块链存储表示
  • 24. 4.2.1 定长顺序存储表示 用一组地址连续的存储单元存储串 值的字符序列,类似于线性表的顺序存储 结构。所谓定长顺序存储结构,是直接使 用定长的字符数组来定义,数组的上界预 先给出: #define MAXSTRLEN 255 // 用户可在 255 以内定义最大串 长 typedef unsigned char SString[MAXSTRLEN + 1];
  • 25. 特点 : 串的实际长度可在这个予定义长 度的范围内随意设定,超过予定义 长度的串值则被舍去,称之为“ 截 断” 。 按这种串的表示方法实现的串的 运算时,其基本操作为 “ 字符序列 的复制 ” 。
  • 26. 1 .串联结 Contcat ( &T,S1,S2 ) S1 [ 0 S2 [ 0 ] ] S1 S2 T T[0] MAXSTRLEN S1[0]+S2[0] <= MAXSTRLEN
  • 27. S1 [ 0 S2 [ 0 ] ] S1 S2 S2 中被截去的 T 字符序列 T[0] MAXSTRLEN S1[0] < MAXSTRSIZE 而 S1[0]+S2[0] > MAXSTRSIZE
  • 28. S1 [ 0 S2 [ 0 ] ] S1 S2 T S2 串被全部截 去 T[0] MAXSTRLEN S1[0] = MAXSTRLEN
  • 29. Status Concat(SString S1, SString S2, SString &T) { if (S1[0]+S2[0] <= MAXSTRLEN) { // 未截断 T[1..S1[0]] = S1[1…S1[0]]; T[S1[0]+1…S1[0]+S2[0]] = S2[1…S2[0]]; T[0] = S1[0]+S2[0]; uncut = TRUE;} else if (S1[0] < MAXSTRSIZE) { // 截断 T[1…S1[0]] = S1[1…S1[0]]; T[S1[0]+1…MAXSTRLEN]=S2[1…MAXSTRLEN - S1[0]]; T[0] = MAXSTRLEN; uncut = FALSE;} else { S1[0] = MAXSTRSIZE // 截断 ( 仅取 S1) T[0...MAXSTRLEN] = S1[0…MAXSTRLEN]; // T[0] == S1[0] == MAXSTRLEN uncut = FALSE; } return uncut; } // Concat
  • 30. 2 .求子串 SubString(&Sub, S, pos, len) Status SubString(SString&Sub, SString S, int pos,int len) { // 用 Sub 返回串 S 的第 pos 个字符起长度为 len 的子串。其 中 1≤pos ≤StrLength(S) 且 0≤len≤StrLength(S)-pos+1 if (pos<1 ||pos>S[0] || len<0 || len>S[0]-pos+1) return ERROR; Sub[1……len]=S[pos…pos+len-1] ; Sub[0]=len ; return OK; } // SubString
  • 31. 定长顺序存储表示的特点与问题 1 . 实现串操作的原操作为“ 字符序列的复制” ,操 作的时间复杂度基于复制的字符序列的长度。 2. 在操作中出现串值序列的长度超过 MaxS trLe n 时,约定用截尾法处理,这种情况可能在联结串 或插入 , 置换时发生。 3. 克服这个问题惟有不限定串长的最大长度,即 动态分配串值的存储空间。
  • 32. 4.2.2 堆分配存储表示 以一组地址连续的存储单元存储串值的字符序 列,存储空间在程序执行过程中动态分配。 C 语言中提供的串类型就是以这种存储方式实 现的。系统利用函数 m allo c () 和 fre e ( ) 进行串值空 间的动态管理,为每一个新产生的串分配一个存储 区,称串值共享的存储空间为“ 堆”。 C 语言中的串以一个空字符为结束符,串长是 一个隐含值。
  • 33. typedef struct { char *ch; // 若是非空串,则按串长分 配存储区 , 否则 ch 为 NULL int length; // 串长度 } HString; 这类串操作实现的算法为: 先为新生成的串分配一个存储空间,然后进行 串值的复制。
  • 34. 1. 串赋值 Status StrAssign(Hstring&T,char*chars){ // 生成一个其值等于串常量 chars 的串 T If ( T.ch ) free (T.ch); // 释放 T 原有空间 for(i=0,c=chars; c; ++i,++c); // 求 chars 的长度 i If ( !i ) {T.ch=NULL; T.length=0;} else{ if(!(T.ch=(char*)malloc(i*sizeof(char)))) exit(OVERFLOW); // 开辟空间再赋值 T.ch[0…i-1]=chars[0…i-1]; T.length=i; } return OK;
  • 35. 2. 串比较 ; Int StrCompare(Hstring S,Hstring T){ for(i=0; i<S.length && i<T.length; ++i) if ( S.ch[i] != T.ch[i] ) Return S.ch[i]-T.ch[i]; Return S.length - T.length // 若 S>T, 则返回值 >0; 若 S=T, 则返回值 =0 ; 若 S<T ,则返回值 =0 } // StrCompare
  • 36. 3. 串联接 Status Concat(Hstring&T,HStringS1,HstringS2) { // 用 T 返回由 S1 和 S2 联接而成的新串 if(T.ch) free(T.ch); // 释放旧空间 if(!(T.ch=(char*)malloc((S1.length+S2.length)* sizeof(char)))) exit(OVERFLOW); T.ch[0…S1.length - 1]= S1.ch[0…S1.length - 1]; T.length= S1.length+ S2.length; T.ch[S1.length…T.length-1]=S2.ch[0…S2.length-1]; return OK; } // Concat
  • 37. 4. 取子串 Status SubString(HString&Sub,Hstring S,int pos,int len) { // 用 Sub 返回串 S 的第 pos 个字符起长度为 len 的子串。 // 其中 1≤pos StrLength(S) 且 0≤ len≤ StrLength(S)-pos+1 if (pos<1 ||pos>S.length || len<0||len>S.length-pos+1) return ERROR; if(Sub.ch) free(Sub.ch); // 释放旧空间 if (!len){ Sub.ch=NULL; Sub.length=0; } // 空子串 else { // 完整子串 Sub.ch= (char*) malloc (len*sizeof(char)); // 取长度 len 分配空 间 Sub.ch[0…len-1]=S.ch[pos-1…pos+len-2] ; Sub.length=len ; return OK;
  • 38. 4.2.3 块链存储表示 以链表存储串值,除头指针外还可 以附设一个尾指针指示链表中的最后一 个结点,并给出当前串的长度。称如此 定义的串存储结构为 块链结构。 结点大小 块链结构
  • 39. #define CHUNKSIZE 80 // 可由用户定义的块大小 typedef struct Chunk { // 结点结构 char ch[CUNKSIZE]; struct Chunk *next; } Chunk; typedef struct { // 串的链表结构 Chunk *head, *tail; // 串的头和尾指针 int curlen; // 串的当前长度 } LString;
  • 40. 例如 : 在编辑系统中,整个文本编辑区可 以看成是一个串,每一行是一个子串,构 成一个结点。即 : 同一行的串用定长结构 (80 个字符 ), 行和行之间用指针相联接。 数据元素所占存储位 存储密度 = 实际分配的存储位
  • 41. 存储密度的大小直接影响着串处理的效 率. 1. 存储密度小 , 运算处理方便 , 但存储占用 量大 . 2. 存储密度小 , 在串处理过程中需要进行内 外存交换的话 , 会因为内外存交换操作过 多而影响处理的总效率 . 串值的链式存储结构对于某些串操作 有一定方便处 , 但总的说来不如另外两种存 储结构灵活 , 它占用存储量大且操作复杂 .
  • 42. 练习 : 设 s=‘I AM A STUDENT’ , t=‘GOOD’ , q=‘WORKER’ ,求: ( 1 ) StrLength(s) , StrLength(t) ( 2 ) SubString(s, 8, 7) , SubString(t, 2, 1) ( 3 ) Index(s, ‘A’,1) , Index(s,t,3) ( 4 ) Replace(s, ‘STUDENT’, q) ( 5) Concat(SubString(s,6,2),Concat(t,SubString(s,7,8)))