网站首页 > 技术教程 正文
4.1 串
4.1.1 定义
串(string):由零个或任意字符组成的有限数列
子串:串中任意连续字符组成的子序列(含空串)称为该串的子串
真子串:不包含自身的所有子串
主串:包含子串的串相应地称为主串
字符位置:字符在序列中的序号为该字符在串中的位置
子串位置:子串第一个字符在主串中的位置
空格串:由一个或多个空格组成的串,与空串不同
串相等:当且仅当两个串的长度相等并且各个对应位置上的字符都相同,这两个串才是相等的
如:“abcd”≠ “abc”
所有空串是相等的
4.1.2 案例引入
串的引用非常广泛,计算机上的非数值处理的对象大部分是字符串数据,例如:文字编辑、符号处理、各种信息处理系统等等
病毒感染检测
- 研究者将人的DNA和病毒的DNA均表示成一些字母组成的字符串序列
 - 然后检测某种病毒DNA序列是否在患者的DNA序列中出现过,如果出现过,则此人感染了该病毒,否则没有感染
 - 例如:假设病毒的DNA序列为baa,患者1的DNA序列为aaabbba,则感染;患者2的DNA序列为babbaa,则未感染
 
(注意,人的DNA序列是线性的,而病毒的DNA序列是环状的)
4.1.3 类型定义、存储结构及其运算
顺序存储
#define MAXSTRINGSIZE 255
typedef struct {
	char ch[MAXSTRINGSIZE + 1];		// 存储串的一维数组
	int length;						// 串的当前长度
}mystring;链式存储
链式存储结构和链表一样
下面这种结构称为:块链结构
#define MAXBLOCKLINKSTRINGSIZE 80
typedef struct BlockLinkString {
	char ch[MAXBLOCKLINKSTRINGSIZE];		// 存储串的一维数组
	struct BlockLinkString* next;			// 指向下一个块的指针
}Block;
typedef struct {
	Block* head;		// 指向串的头块
	Block* tail;		// 指向串的尾块
	int length;			// 串的当前长度
}blockLinkString;模式匹配算法
算法目的:确定主串中所含子串(模式串)第一次出现的位置(定位)
算法应用:搜索引擎、拼写检查、语言翻译、数据压缩
算法种类:
- BF(Brute-Force),又称古典的、经典的、朴素的、穷举的
 - KMP算法(特点:速度快)
 
BF算法
算法思路:
- 将主串的第pos个字符和模式串的第一个字符比较
 
- 若相等,继续逐个比较后续字符
 - 若不等,从主串的下一个字符起,重新与模式串的第一个字符比较
 
- 直到主串的一个连续子串字符序列与模式串相等。返回值与S中T匹配的子序列第一个字符的序号,即匹配成功。
 - 否则,匹配失败,返回值 0
 
/*******************************************************************************************************************************
 * @description:BF算法
 * @param:S	主串
 * @param:T	子串
 * @param:pos	开始位置
 * @return:	匹配成功返回1;否则返回0
 */
int index_BF(mystring S, mystring T, int pos)
{
	int i = pos;
	int j = 1;
	while (i <= S.length && j <= T.length)
	{
		if (S.ch[i] == T.ch[j]){
			++i;
			++j;
		}
		else{
			i = i - j + 2;	// 回溯
			j = 1;
		}
	}
	if (j > T.length)	// 匹配成功
		return i - T.length;
	else
		return 0;
}时间复杂度:O(n*m)
KMP算法
利用已经部分匹配的结果而加快模式串的滑动速度,且主串S的指针I不必回溯,可提速到O(n+m)
因此需要一个next[j]数组,表明当模式中第j个字符与主串中相应字符“失败”时,在模式中需要重新和主串中该字符进行比较的字符的位置
例如:
next函数的改进
if(pattern[j] == pattern[i]){
    next[i] = j+1;
    i++;
    j++;
}
else{
    next[i] = j-1;
    j++;
    i++;
}/*******************************************************************************************************************************
 * @description:构造next数组
 * @param:T	模式串
 * @param:next
 */
static void get_next(mystring T, int next[])
{
	int i = 1;
	int j = 0;
	next[1] = 0;
	while (i < T.length)
	{
		if (j == 0 || T.ch[i] == T.ch[j])
		{
			++i;
			++j;
			if (T.ch[i] != T.ch[j])
				next[i] = j;
			else
				next[i] = next[j];
		}
		else
			j = next[j];
	}
}
/*******************************************************************************************************************************
 * @description:KMP算法
 * @param:S	主串
 * @param:T	模式串
 * @param:pos	开始位置
 * @return:
 */
int index_KMP(mystring S, mystring T, int pos)
{
	int i = pos;
	int j = 1;
	int next[255];
	get_next(T, next);
	while (i <= S.length && j <= T.length)
	{
		if (j == 0 || S.ch[i] == T.ch[j]) {
			++i;
			++j;
		}
		else
			j = next[j];
	}
	if (j > T.length)
		return i - T.length;
	else
		return 0;
}测试代码
void StringMain()
{
	mystring S = { ' ', 'a','a','a','b','a','a','a','a','b' };		// 主串,第一个位置不用
	S.length = 9;
	mystring T = { ' ','a','a','a','a' };							// 模式串,第一个位置不用
	T.length = 4;
	printf("主串:");
	printString(S);
	printf("\n模式串:");
	printString(T);
	// 测试BF算法
	int pos = index_BF(S, T, 1);
	if (pos)
		printf("\nBF算法:匹配成功,位置为:%d\n\n", pos);
	else
		printf("\nBF算法:匹配失败\n\n");
	// 测试KMP算法
	pos = index_KMP(S, T, 1);
	if (pos)
		printf("\nKMP算法:匹配成功,位置为:%d\n", pos);
	else
		printf("\nKMP算法:匹配失败\n");
}4.2 数组
数组:按一定格式排列起来的具有相同类型的数据元素的集合
一维数组:若线性表中的数据元素为非结构的简单元素,则称为一维数组
一维数组的逻辑结构:线性结构。定长的线性表
声明格式:数据类型 变量名称[长度];
二维数组:若一维数组中的数据元素又是一维数组结构,则称为二维数组。
二维数组的逻辑结构:
- 非线性结构:每一个数据元素即在一个行表中,又在一个列表中
 - 线性结构:该线性表的每个数据元素也是一个定长的线性表
 
数组特点:结构固定-定义后,维数和维界不再改变
数组基本操作:除了结构的初始化和销毁之外,只有取元素和修改元素值的操作
4.2.1 抽象数据类型定义
二维数组存储方式:
- 以行序为主序:C、PASCAL、JAVA、Basic
 
- 以列序为主序:FORTRAN
 
4.2.2 特殊矩阵的压缩存储
什么时压缩存储?
为多个相同的非零元素只分配一个存储空间;对零元素不分配空间
什么样的矩阵能够压缩?
一些特殊矩阵:对称矩阵,对角矩阵,三角矩阵,稀疏矩阵等
什么叫稀疏矩阵?
矩阵中非零元素的个数较少(一般小于5%)
对称矩阵
三角矩阵
对角矩阵
稀疏矩阵
三元组
十字链表
例如:
4.3 广义表
4.3.1 定义
广义表(又称列表Lists)是n≥0个元素 a0,a1,... ,a(n-1)的有限序列,其中每一个ai或者是原子,或者是一个广义表
例如:
广义表的性质:
- 广义表中的数据元素有相对次序;一个直接前驱和一个直接后继
 - 广义表的长度定义为最外层所包含元素的个数;如:C = (a,(b, c))是长度为2的广义表
 - 广义表的深度定义为该广义表展开后所含括号的重数;A = (b, c)的深度为1,B = (A, b)的深度为2,C = (f, B, h)的深度为3 注意:“原子”的深度为 0;“空表”的深度为 1
 - 广义表可以为其它广义表共享;如:广义表B就共享表A。在B中不必列出A的值,而是通过名称来引用,B = (A)
 - 广义表可以是一个递归的表,如 F = (a, F=(a, (a, (a, ...)))) 注意:递归表的深度是无穷值,长度是有限值
 - 广义表是多层次结构,广义表的元素可以是单元素,也可以是子表,而子表的元素还可以是子表
 
4.3.2 基本运算
- 求表头GetHead(L):非空广义表的第一个元素,可以是一个原子也可以是一个子表
 - 求表尾GetTail(L):非空广义表除去表头元素以外其它元素所构成的表。表尾一定是一个表
 
猜你喜欢
- 2024-11-13 软件开发究竟难在哪?(软件开发越来越难做)
 - 2024-11-13 PHP是否越来越不受欢迎?(php没人用了)
 - 2024-11-13 如何快速申请软件著作权(申请软件著作权需要什么资料)
 - 2024-11-13 这个开源项目用了7年,整理了全网经典的编程书籍
 - 2024-11-13 变量初始化你真的懂吗(变量初始化你真的懂吗什么意思)
 - 2024-11-13 ubuntu 20.04安装gfortran gcc(ubuntu安装gcc5.4)
 - 2024-11-13 5年程序员总结—这几个C语言问题超纲了,小白勿进
 - 2024-11-13 字符和字符串你不知道的东西(字符与字符串的区别)
 - 2024-11-13 Python术语对照表(上)(python 术语)
 - 2024-11-13 蝌学荐书|菲尔兹奖得主陶哲轩15岁时写的数学思维入门书,凭什么能畅销5万册?
 
欢迎 你 发表评论:
- 10-23Excel计算工龄和年份之差_excel算工龄的公式year
 - 10-23Excel YEARFRAC函数:时间的"年份比例尺"详解
 - 10-23最常用的10个Excel函数,中文解读,动图演示,易学易用
 - 10-23EXCEL中如何计算截止到今日(两个时间中)的时间
 - 10-2390%人不知道的Excel神技:DATEDIF 精准计算年龄,告别手动算错!
 - 10-23计算工龄及工龄工资(90%的人搞错了):DATE、DATEDIF组合应用
 - 10-23Excel中如何计算工作日天数?用这两个函数轻松计算,附新年日历
 - 10-23怎样快速提取单元格中的出生日期?用「Ctrl+E」批量搞定
 
- 最近发表
 - 
- Excel计算工龄和年份之差_excel算工龄的公式year
 - Excel YEARFRAC函数:时间的"年份比例尺"详解
 - 最常用的10个Excel函数,中文解读,动图演示,易学易用
 - EXCEL中如何计算截止到今日(两个时间中)的时间
 - 90%人不知道的Excel神技:DATEDIF 精准计算年龄,告别手动算错!
 - 计算工龄及工龄工资(90%的人搞错了):DATE、DATEDIF组合应用
 - Excel中如何计算工作日天数?用这两个函数轻松计算,附新年日历
 - 怎样快速提取单元格中的出生日期?用「Ctrl+E」批量搞定
 - Excel日期函数之DATEDIF函数_excel函数datedif在哪里
 - Excel函数-DATEDIF求司龄_exceldatedif函数计算年龄
 
 
- 标签列表
 - 
- 下划线是什么 (87)
 - 精美网站 (58)
 - qq登录界面 (90)
 - nginx 命令 (82)
 - nginx .http (73)
 - nginx lua (70)
 - nginx 重定向 (68)
 - Nginx超时 (65)
 - nginx 监控 (57)
 - odbc (59)
 - rar密码破解工具 (62)
 - annotation (71)
 - 红黑树 (57)
 - 智力题 (62)
 - php空间申请 (61)
 - 按键精灵 注册码 (69)
 - 软件测试报告 (59)
 - ntcreatefile (64)
 - 闪动文字 (56)
 - guid (66)
 - abap (63)
 - mpeg 2 (65)
 - column (63)
 - dreamweaver教程 (57)
 - excel行列转换 (56)
 
 

本文暂时没有评论,来添加一个吧(●'◡'●)