第四章 串.

Slides:



Advertisements
Similar presentations
单元二:面向对象程序设计 任务二:借书卡程序设计.
Advertisements

新材料作文.
第7章 樹與二元樹 (Trees and Binary Trees)
AI人工智慧報告 黑白棋 班級:資工四乙 學號:498G0009 姓名:盧冠妤.
第三章 鏈結串列 Linked List.
第 5 章 流程控制 (一): 條件分支.
数据结构——树和二叉树 1/96.
第五章 树 东南大学计算机学院 方效林 本课件借鉴了清华大学殷人昆老师 和哈尔滨工业大学张岩老师的课件.
第8章 字串與陣列 8-1 字串處理 8-2 一維陣列的處理 8-3 建立多維陣列 8-4 不規則陣列與參數傳遞 8-5 陣列排序與搜尋.
数据结构与算法 数据结构与算法实验
C++程序设计 王希 图书馆三楼办公室.
Linked List Operations
單向鏈結串列 Singly Linked Lists.
第4章 串 串的基本概念和C语言的串函数 串的存储结构 动态数组实现的顺序串 串的模式匹配算法——BF算法 主要知识点.
数据结构 Data Structure 主讲人:王国军,郑瑾 中南大学 中南大学信息院计科系
高级语言程序设计 主讲人:陈玉华.
第二章 C# 基础知识.
佇列 (Queue).
补充内容 结构体 概述 定义结构体类型和定义结构体变量 结构体变量的引用 结构体变量的初始化 指针与结构体 用typedef定义类型的别名.
If … else 選擇結構 P27.
C++语言程序设计 C++语言程序设计 第六章 指针和引用 第十一组 C++语言程序设计.
·线性表的定义及ADT ·线性表的顺序存储结构 ·线性表的链接存储结构 · 单向循环链表 · 双链表、双向循环链表 · 一元多项式的加法
QQ: 李祥 QQ: 欢迎多种方式的学习交流,祝大家学有所成.
数据结构 第4章 串.
授课老师:龚涛 信息科学与技术学院 2018年3月 教材: 《Visual C++程序员成长攻略》 《C++ Builder程序员成长攻略》
cn/~dongeliu/dsa.html 刘 东 信息学院6系 中国科学技术大学
第4章 程序控制结构与算法基础.
流程控制、陣列 台南市聖功女子高級中學 毛全良.
串和数组.
第十章 C高级程序应用—链表* 10.1链表的基本概念 10.2单向链表 10.3双向链表 10.4应用举例.
第5章 堆疊(Stacks) 5-1 堆疊的基礎 5-2 堆疊的表示法 5-3 堆疊的應用 - 運算式的計算與轉換
第5章 堆疊(Stacks) 5-1 堆疊的基礎 5-2 堆疊的表示法 5-3 堆疊的應用 - 運算式的計算與轉換
1.1 数据结构讨论的范畴 1.2 基本概念 1.3 算法和算法的量度.
第 3 讲 线性表(一).
第三章 栈和队列.
第二章 线性表.
陈海明 副教授 信息学院 计算机系 电子信息类非计算机专业选修课 程序设计实践 陈海明 副教授 信息学院 计算机系
4.1 串的抽象数据类型的定义 4.2 串的表示和实现 4.3 串的模式匹配算法.
第4章 常量和变量 常量和变量都是程序中预留的用于保存数据的内存空间。常量的值在程序运行过程中始终不会发生变化。而变量的值在程序的运行过程中是可以变化的。在Fortran语言中,有五种基本的数据类型可供使用。他们分别是整型(INTEGER)、实型(REAL)、复型(COMPLEX)、字符型(CHARACTER)和逻辑型(LOGICAL)。按用途,又可以分数值型、字符型和逻辑型三种。相应的常量和变量也可以分为这三种。本章将按照用途介绍常量和变量的基本概念。
第三章 栈和队列.
第四章串 4.1 串类型定义 4.2 串的表示和实现 4.3 串的模式匹配算法 4.4 串操作应用举例.
C++语言程序设计 C++语言程序设计 第七章 类与对象 第十一组 C++语言程序设计.
資料結構 第4章 堆疊.
第1章 概述 本章要点: C语言程序结构和特点 C语言程序的基本符号与关键字 C语言程序的编辑及运行 学习方法建议:
第五章 串和数组 5.1 串的定义和操作 5.2 串的表示和实现 5.3 字符串应用 5.4 字符串匹配算法 5.5 数组
第四章 串.
江西财经大学信息管理学院 《数据库应用》课程组2007
7.1 广义表的概念 广义表是n(n≥0)个数据元素组成的序列,其中每个数据元素或是单个数据元素(简称原子),或仍然是一个广义表 。
第五章 递归与广义表 递归的概念 递归过程与递归工作栈 递归与回溯 广义表.
C语言概述 第一章.
程式結構&語法.
第1章 绪论 2019/4/16.
第五章 串和数组 5.1 串的定义和操作 5.2 串的表示和实现 5.3 字符串应用 5.4 字符串匹配算法 5.5 数组
第7章 樹與二元樹(Trees and Binary Trees)
保留字與識別字.
程式的時間與空間 Time and Space in Programming
字符串 (String) 字符串是 n (  0 ) 个字符的有限序列, 记作 S = “c1c2c3…cn” 其中,S 是串名字
C++语言程序设计教程 第2章 数据类型与表达式 第2章 数据类型与表达式 制作人:杨进才 沈显君.
<编程达人入门课程> 本节内容 为什么要使用变量? 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ:
第 六 讲 栈和队列(一).
本节内容 Lua基本语法.
第四章 串 £4.1 串的定义 £4.2 串的顺序存储结构 £4.3 串的链式存储结构 £4.4 串的应用—文本编辑
#include <iostream.h>
第二章 Java基本语法 讲师:复凡.
C++语言程序设计 C++语言程序设计 第二章 基本数据类型与表达式 第十一组 C++语言程序设计.
第五章 逻辑运算和判断选取控制 §5.1 关系运算符和关系表达式
第1章 数据结构基础概论 本章主要介绍以下内容 数据结构研究的主要内容 数据结构中涉及的基本概念 算法的概念、描述方法以及评价标准.
基本資料型態 變數與常數 運算子 基本的資料處理 授課:ANT 日期:2014/03/03.
Chapter 2 Entity-Relationship Model
第六章 复合数据类型 指针的声明与使用 数组的声明与使用 指针与数组的相互引用 字符串及相关库函数 new与delete
Presentation transcript:

第四章 串

4.1 串的抽象数据类型的定义 4.2 串的表示和实现 4.3 文本编辑 —串的应用举例

数据关系: ADT String { D={ ai |ai∈CharacterSet, i=1,2,...,n, n≥0 } 串是有限长的字符序列,由一对双引号相括,如:  a string  数据对象: D={ ai |ai∈CharacterSet, i=1,2,...,n, n≥0 } 数据关系: R1={ < ai-1, ai > | ai-1, ai ∈D, i=2,...,n }

基本操作: StrAssign (&T, chars) DestroyString(&S) StrCopy (&T, S) StrLength(S) StrEmpty (S) Concat (&T, S1, S2) StrCompare (S, T)

SubString (&Sub, S, pos, len) ClearString (&S) Index (S, T, pos) Replace (&S, T, V) StrInsert (&S, pos, T) StrDelete (&S, pos, len) } ADT String

初始条件:chars 是字符串常量。 操作结果:把 chars 赋为 T 的值。 初始条件:串 S 存在。 StrAssign (&T, chars) (串赋值) 初始条件:chars 是字符串常量。 操作结果:把 chars 赋为 T 的值。 StrCopy (&T, S) (串复制) 初始条件:串 S 存在。 操作结果:由串 S 复制得串 T。

初始条件:串 S 存在。 操作结果:若 S 为空串,则返回 TRUE, 否则返回 FALSE。(为空串) 初始条件:串 S 存在。 StrEmpty (S) (判空) 初始条件:串 S 存在。 操作结果:若 S 为空串,则返回 TRUE, 否则返回 FALSE。(为空串) StrLength (S) (求长度) 初始条件:串 S 存在。 操作结果:返回串 S 中字符的个数。

例如:StrCompare( data ,  state ) < 0 StrCompare (S, T) (串比较) 初始条件:串 S 和 T 都存在。 操作结果:由串 S 小于或等于或大于串 T 分别返回小于或等于或大于 0 的值 。 例如:StrCompare( data ,  state ) < 0 StrCompare( cat ,  case ) > 0

Concat (&T, S1, S2) (串联接) 初始条件:串 S1 和 S2 存在。 操作结果: T 为由串 S1 和串 S2 联接 所得的串。 例如: Concat( T, man, kind) 求得 T = mankind Concat( T, kind, man) 求得 T = kindman

(求子串) 初始条件: 操作结果: 以 Sub 返回串 S 中第 pos 个字符起 串 S 存在,1≤pos≤StrLength(S) SubString (&Sub, S, pos, len) (求子串) 初始条件: 操作结果: 以 Sub 返回串 S 中第 pos 个字符起 长度为 len 的子串。 串 S 存在,1≤pos≤StrLength(S) 且 0≤len≤StrLength(S)-pos+1。

子串为“串”中的一个字符子序列 例如: SubString( sub, commander , 4, 3) 求得 sub = man  SubString( sub, commander  , 1, 9) 求得 sub = commander  SubString( sub, commander , 9, 1) 求得 sub = r 

SubString(sub, commander, 4, 7) SubString(sub, beijing, 7, 2) = ? sub = ? 起始位置和子串长度之间存在约束关系 SubString(student, 5, 0) =  长度为 0 的子串为“合法”串

串 S 和 T 存在,且 T 是非空串, 1≤pos≤StrLength(S)。 操作结果: 若主串 S 中存在和串 T 值相同的 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;

初始条件: 串 S, T 和 V 均已存在, 且 T 是非空串。 操作结果: 用 V 替换主串 S 中出现的所有与 Replace ( S, T, V) (串置换) 初始条件: 串 S, T 和 V 均已存在, 且 T 是非空串。 操作结果: 用 V 替换主串 S 中出现的所有与 (模式串)T 相等的不重叠的子串。

例如: 假设 S = abcaabcaaabca, T = bca  bca bca bca 若 V = x , 则经置换后得到 S = axaxaax  若 V = bc , 则经置换后得到 S = abcabcaabc

StrInsert (&S, pos, T) (插入) 1≤pos≤StrLength(S)+1。 操作结果:在串 S 的第 pos 个字符之前 插入串T。 例如:S = chater ,T = rac , 则执行 StrInsert(S, 4, T) 之后得到 S = character 

StrDelete (&S, pos, len) (删除) 初始条件: 串 S 存在,且 1≤pos≤StrLength(S)-len+1。 操作结果: 从串 S 中删除第 pos 个字符起 长度为len的子串。

对于串的基本操作集可以有不同的定义方法,在使用高级程序设计语言中的串类型时,应以该语言的参考手册为准。 在上述抽象数据类型定义的13种操作中, 串赋值 StrAssign、串复制 Strcopy、 串比较 StrCompare、求串长 StrLength、 串联接 Concat 以及求子串 SubString 等六种操作构成串类型的最小操作子集。

? 利用串比较、求串长和求子串等操作实现定位函数 Index( S, T, pos )算法的基本思想为: StrCompare(SubString(S, i, StrLength(T)), T ) pos S 串 T 串 i T 串 i T 串 i T 串 i 或者 = n-m+1

int Index (String S, String T, int pos) { // T为非空串。若主串S中第pos个字符之后存在与 T相等的子串, // 则返回第一个这样的子串在S中的 位置,否则返回0 if (pos > 0) { } // if return 0; // S中不存在与T相等的子串 } // Index n = StrLength(S); m = StrLength(T); i = pos; while ( i <= n-m+1) { } // while SubString (sub, S, i, m); if (StrCompare(sub,T) != 0) ++i ; else return i ;

news 串 实现置换函数 Replace( S, T, V)算法的基本思想为: pos = i+m pos= n-tn+1 pos i sub T 串 V 串 tn news 串 sub V 串

void replace(String& S, String T, String V) { } n=StrLength(S); m=StrLength(T); pos = 1; StrAssign(news, NullStr); i=1; while ( pos <= n-m+1 && i) { i=Index(S, T, pos); if (i!=0) { SubString(sub, S, pos, i-pos); // 不置换子串 Concat(news, news, sub, V); pos = i+m; }//if }//while SubString(sub, S, pos, n-pos+1); // 剩余串 Concat( S, news, sub );

串的逻辑结构和线性表极为相似,区别 仅在于串的数据对象约束为字符集。 串的基本操作和线性表有很大差别。 在线性表的基本操作中,大多以“单个元素”作为操作对象; 而在串的基本操作中,通常以“串的整体”作为操作对象。

在早期的程序设计语言中,串只是作为输入或输出的常量出现,则只需存储此串的串值,即字符序列即可。之后在多数非数值处理的程序中,串均以变量的形式出现,因此作为一个数据类型也就存在一个存储表示和实现的问题。

一、串的定长顺序存储表示 二、串的堆分配存储表示 三、串的块链存储表示

char str[10]; 用一组地址连续的存储单元存储串值。 例如,在 C 语言中可以定义串为 这表示,为串变量 str 分配了一个固定长度为 10 的数组空间,而 str 的实际长度可以在这个定义范围内随意,但最大长度不得超过 9 (串的结束符\0也占一个字符的空间,但它不属串值本身)。

void Concat( char T[ ], char S1[ ], char S2[ ] ) { // T 串为由 S2 串联接到 S1 串构成的新串 j=0; k=0; while ( S1[j] != \0 ) T[k++] = S1[j++]; // 复制串S1 j = 0; while ( S2[j] != \0 ) T[k++] = S2[j++]; // 接着复制串S2 T[k] = \0; // 置结果串T的结束标志 } // Concat

bool SubString_Sq(char Sub[], char S[],int pos, int len){ // 以 Sub 返回串 S 中第 pos 个字符起长度为 len 的子串 if (pos<1) return FALSE; }//SubString_Sq i=0; while (i<pos-1 && S[i]!= \0  ) i++; if ( i<pos-1 || S[i]==  \0  ) return FALSE; else { k=0; while ( k< len && S[i] !=  \0  ) Sub[k++] = S[i++]; if ( k<len ) return FALSE; else { Sub[k] =  \0  ; return TRUE; } }//else

int Index (char S[ ], char T[ ], int pos) { // T为非空串。若主串S中第 pos 个字符之后存在与 T相等的子串, // 则返回第一个这样的子串在S中的 位置,否则返回0 if (pos > 0) { } // if return 0; // S中不存在与T相等的子串 } // Index i = pos-1; j = 0; while ( S[i+j] != \0 && T[j] != \0 ) { if ( S[i+j] == T[j] ) j ++; // 继续比较后继字符 else { i ++; j = 0; } // 重新开始新的一轮比较 if ( T[j] == \0 ) return (i+1); // 匹配成功 else return 0; // 不存在和串T相同的子串

i i i i 算法的基本思想: S 串 T 串 pos n-m+1 具体实现时的两种情况: j j S 串 j j j T 串 T 串 或者继续重复新一轮匹配过程,如此反复直至 (i+j)>Strlength(S)表明匹配不成功 具体实现时的两种情况: 比较不等,i增1,j回退至T串的起始位置 i i i j j S 串 j j j T 串 T 串 开始新一轮的匹配直至匹配成功此时 j>Strlength(T) T 串

C 语言中提供的串类型就是以这种存储方式实现的。 仍以一组地址连续的存储空间存储串值,只是串变量的存储空间是在程序执行过程中利用 new 进行动态分配得到的。程序中出现的所有串变量的值都存储在一个称之为“堆”的共享空间中。此时的串操作仍基于“字符序列的复制”进行。 C 语言中提供的串类型就是以这种存储方式实现的。

void Concat( char *T, char *S1, char *S2 ) { // T 串为由 S2 串联接到 S1 串构成的新串 slen1 = StrLength(S1); slen2 = StrLength(S2); T = new char[slen1+slen2]; j=0; k=0; while ( S1[j] != \0 ) T[k++] = S1[j++]; //复制串S1 j = 0; while ( S2[j] != \0 ) T[k++] = S2[j++]; // 接着复制串S2 T[k] = \0; // 置结果串T的结束标志 } // Concat

bool StrInsert (char* S, int pos, char* T) { // 在串 S 的第 pos(1≤pos≤StrLength(S)+1) 个字符 // 之前插入串T slen=StrLength(S); tlen=StrLength(T); // 求串长 char S1 [slen +1] ; // 设S1为辅助串空间 if (pos < 1 || pos > slen+1) return FALSE; // 插入位置不合法; if (tlen>0) { } } // StrInsert // T非空,则为S重新分配空间并插入T

i=0; while ((S1[i]=S[i]) != \0) i++; // 暂存串S S = new char[slen + tlen +1]; // 重新分配空间 for ( i=0, k=0; i<pos-1; i++) S[k++] = S1[i]; // 保留插入位置之前的子串 j = 0; while ( T[j]!= \0) S[k++] = T[j++]; // 插入T while ( S1[i] != \0) S[k++] = S1[i++]; // 复制插入位置之后的子串 S[k] = \0; // 置串S的结束标志

和线性表类似,串也有链式存储结构,即以链表存储串值。由于串的数据元素是一个字符,它只有 8 位二进制数,因此用链表存储串值时,通常一个结点中存放的不是一个字符,而是一个“子串” 。 数据元素所占存储位 存储密度 = 实际分配的存储位

typedef struct Chunk { // 结点结构 char ch[CUNKSIZE]; struct Chunk *next; #define CHUNKSIZE 80 // 可由用户定义的块大小 typedef struct Chunk { // 结点结构 char ch[CUNKSIZE]; struct Chunk *next; } Chunk; typedef struct { // 串的链式存储映象 Chunk *head, *tail; // 串的头和尾指针 int curlen; // 串的当前长度 } LString;

实际应用时,结点的大小可以根据问题所需来设置。 例如,在编辑系统中,可以将整个文本编辑区看成是一个“串” ,每一行是一个子串。采用链表结构,可设结点大小为一行中的字符个数。即: 同一行的串用定长结构(80个字符), 行和行之间用指针相联接。

正文编辑程序是一个面向用户的系统服务程序,广泛用于源程序的输入和修改,甚至用于报刊和书籍的编辑排版以及办公室的公文书信的起草和润色等。 正文编辑的实质是修改字符数据的形式或格式。虽然各种正文编辑程序的功能强弱不同,但其基本功能大致相同,一般都包括串的查找、插入、删除和修改等基本操作。

为了编辑方便起见,用户可以通过换页符和换行符将正文划分为若干页和若干行(或者直接划分为若干行)。在编辑程序中,则可将整个正文看成是一个“正文串”,页是正文串的子串,而行则是页的子串。 为了管理正文串中的页和行,编辑程序要为正文串建立相应的页表和行表,页表的每一项列出页号和该页的起始行号,行表的每一项则指示每一行的行号、起始地址和该行子串的长度。

main(){ float a,b,max; scanf(%f,%f,&a,&b); if a>b max=a; else max=b; }; (a>b) max=a; m a i n ( ) { ↙   f l o t , b x ; s c  % & > = e } i f ( a > b ) m a x = a ; 284

假设该正文串只占一页,起始行号为100,起始的存储地址为200,则其行表如下: 起始地址 长度 100 200 8 102 208 17 104 225 24 105 249 106 266 15 108 281 3 284 19 2

在正文编辑程序中设立页指针、行指针和字符指针,分别指示当前操作的页、行和字符。 如果在某行内插入或删除若干字符,则要修改行表中该行的长度,若该行长度因插入而超出了原分配给它的存储空间,则要为该行重新分配存储空间,并修改该行的起始位置。

1. 熟悉串的七种基本操作的定义,并能利用这些基本操作来实现串的其它各种操作的方法。 2. 了解串的各种存储结构的特点及其适用场合。