二维数组m的元素是4个字符组成的串_串、数组和广义表
1. 串
1.1 串的定义
ADT String{ 数据对象:D={ai|ai∈CharacterSet, i=1, 2, …, n, n≧0} 数据关系:R1={|ai-1, ai∈D, i=2, …, n} 基本操作: 生成一个值等于chars的串 复制一个串 判断串是否空串 比较串的大小 返回串元素的个数 将串清空 将串合并 返回串的指定下标的元素之后指定长度的字串 在某个串中查找规定子串,并返回指定下标的字符后第一次出现的位置 在某个串中用规定字串替代不重叠的另一规定字串 在串的指定下标的字符前插入一个指定子串 在串中删除一个规定下标开始指定长度的字串 销毁串}
1.2 串的存储结构
1.2.1 顺序存储
//----------串的定长顺序存储结构---------------
#define MAXLEN 255 //串的最大长度typedef struct {char ch[MAXLEN+1]; //存储串的一维数组,从下标为1开始存储int length; //串的当前长度}SString;
//----------串的堆式顺序存储结构,按需分配长度----------------typedef struct {char *ch; //如果是非空串,则按照串长分配存储区,否则ch为nullint length; //串的当前长度}HString;
1.2.2 链式存储
#define CHUNKSIZE 80typedef struct Chunk{char ch[CHUNKSIZE]; //提高空间利用率(一个结点多个字符)struct Chunk *next; //最后一个结点不满用非串字符填满}Chunk;
typedef struct{ Chunk *head, *tail; //尾指针便于操作int length; //串的当前长度}LString;
1.3 模式匹配算法
1.3.1 BF算法
int Index_BF(SString S, SString T, int pos){//返回模式T在主串S中第pos个字符开始第一次出现的位置。若不存在,则返回值为0//T非空,0int 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;} //如果失配,则将i退回到主串开始比较的下一个字符,j退回到字串的开头}if (j>T.length) return (i-T.length); //匹配成功else return 0; //匹配失败 }
1.3.2 KMP算法
设计思想
失配时,主串指示器i不用回溯,利用已经得到的部分匹配,将模式串指示器j向右滑动尽可能远的距离后继续比较
为此定义next函数,表示模式中第j个字符失配时,在模式串中需要重新与主串中该字符进行比较的字符的位置
故算法如下
int Index_KMP(SString S, SString T, int pos){ //利用模式串T的next函数求T在主串S中第pos个字符之后的位置//其中T非空,1<=pos<=S.lengthint i=pos; int j=1;while (i<S.length && j<T.length) //两个串均未到达串尾{if(j==0 || S.ch[i]==T.ch[j]){++i; ++j;} //如果j为0或者目前的字符匹配,则继续比较下一个字符else j=next[j]; //否则就将j置为next[j]}if (j>T.length) return (i-T.length); //匹配成功else return 0; //匹配失败}
next函数求法
递推求值
由定义知,
next[1] = 0
设next[j]=k,表明有
1k满足上式,此时next[j+1]的值有以下两种情况
(1)pk=pj,则有
故
next[j+1]=k+1=next[j]+1
(2)pk≠pj
此时用把求next值的问题看成模式匹配的问题,模式串既是主串又是模式串
求next[j+1],第j+1个字符与主串失配,假设此时将k=next[j]及其前面的字符串滑过来与主串匹配,由于pk≠pj,此时第k个字母与主串失配,因此我们应当在它前面寻找k’=next[k]继续与主串匹配,以此类推,直到某个字符匹配成功或p[k+1]=1
故
next[j+1]=next[k]+1
算法如下:
void get_next(SString T, int next[]){//求模式串T的next函数值并存入数组nextint i=1;next[1]=0;int j=0;while (i<T.length){if(j==0||T.ch[i]==T.ch[j]){++i; ++j; next[i]=j;} //如果j是0(开头)或者第i个字符等于第j个字符,则next[i+1]=j+1else j=next[j]; //如果不等于,j回溯到next[j]}}
但是,例如串"aaaab"与"aaabaaaab",第4个字母失配,但是还要将j=3,2,1依次与i=4比较,但由于j=1,2,3,4的字符都相等且i=4字符与j=4字符不等,因此可以直接比较i=5和j=1。
由此可见,当next[j]=k,而tj=tk时,不必比较,可以直接比较tj和tnext[k]
,以此类推
算法如下:
void get_nextval(SString T, int nextval[]){//求模式串中next函数的修正值并存入数组nextvalint i=1;nextval[1]=0;int j=0;while (i<T.length){if(j==0||T.ch[i]==T.ch[j]){++i;++j;if(T.ch[i]!=T.ch[j]) nextval[i]=j;else nextval[i]=nextval[j]; //如果第i个字符与第j个字符相等,j回溯到nextval[j]}else j=nextval[j];}}
2. 数组
2.1 定义
ADT Array{ 数据对象:ji = 0, …, bi-1, i=1,2,…,n D = {aj₁j₂…jn | n>0 称为数组的维数,bi是第i维的长度} ji是数组元素第i维下标,aj₁j₂…jn∈ElemSet} 数据关系:R = {R1, R2, …, Rn} Ri = {}} 0<=jk<=bk-1, 1<=k<=n 且k≠i 0<=ji<=bi-2 aj₁…ji…jn, aj₁…ji+1…jn∈D, i = 2, …, n} 基本操作: 构造数组 销毁数组 赋值指定的元素 返回指定的元素值}
2.2 数组的顺序存储
位置下标:LOC(i,j)=LOC(0,0)+(n*i+j)L(可推广至n维)
2.3 特殊矩阵的压缩
对称矩阵(aij = aji)
以sa[a(a+1)/2]存储下三角,则对于下标k有三角矩阵(只有半边有元素,剩下半边元素值相等)
其它矩阵
(1)对角矩阵:找规律,压缩
(2)稀疏矩阵:三元组表(行下标,列下标,值)
3. 广义表
3.1 定义
一些结论
(1)元素可以是原子或者子表
(2)可以为其它广义表共享,可以共享其它广义表
(3)广义表是一个递归的表重要运算
(1)取表头:取出非空广义表的第一个元素,可以是单原子或者子表
(2)取表尾:取出除了第一个元素之外,其余元素构成的表
3.2 存储结构
表结点由标志域(1表示表结点,0表示原子结点),表头结点,表尾结点组成,原子由标志域和和值组成
(a,(b,c,d))结构图示如下
二维数组m的元素是4个字符组成的串_串、数组和广义表相关推荐
- python中求二维数组元素之和_python二维列表求解所有元素之和
相信很多初学小伙伴都会遇到二维列表求解所有元素之和问题,下面给出两种两种常见的求和方法. 方法1: 思想:遍历整个二维列表元素,然后将所有元素加起来 1 def Sum_matrix(matrix): ...
- python 二维列表获取其中元素_Python中二维列表如何获取子区域元素的组成
用过NumPY的应该都知道,在二维数组中可以方便地使用区域切片功能,如下图: 而这个功能在Python标准库的List中是不支持的,在List中只能以一维方式来进行切片操作: 但有时候我只想用一下这个 ...
- QT-C++二维码生成工具(支持中文等任何字符的使用)
QT-C++二维码生成工具 前言 1.效果预览 1.核心程序 全部程序 前言 QT/C++生成二维码程序,支持二维码图片本地保存功能. 1.效果预览 1.核心程序 如下: // 生成二维码图片QStr ...
- php 合并重复数据合并,PHP_php合并数组中相同元素的方法,本文实例讲述了php合并数组中 - phpStudy...
php合并数组中相同元素的方法 本文实例讲述了php合并数组中相同元素的方法.分享给大家供大家参考.具体如下: 关于重复数组的删除我们都介绍过N种方法了,今天这个例子有点不同就是 删除数组中相同的元素 ...
- 二维矩阵中行列元素互换(例题
#include <stdio.h>int main() {int a[2][3]={{1,2,3},{4,5,6}};int b[3][2],i,j;printf("array ...
- 二维数组的认识及其表示元素的两种方式
/*============================================================================Name : TeatArr.cAuthor ...
- 【C 语言】数组 ( 验证二维数组内存是线性的 | 打印二维数组 | 以一维数组方式打印二维数组 | 打印二维数组值和地址 )
文章目录 一.验证二维数组内存是线性的 1.打印二维数组 2.以一维数组方式打印二维数组 3.打印二维数组值和地址 二.完整代码示例 一.验证二维数组内存是线性的 验证二维数组内存是线性的 : 验证方 ...
- C++指针数组、数组指针、数组名及二维数组技巧汇总
本文较为详细的分析了关于理解C++指针数组,数组指针,数组名,二维数组的一些技巧.是比较重要的概念,相信对于大家的C++程序设计有一定的帮助作用. 一.关于数组名 假设有数组: int a[3] = ...
- numpy二维数组改变某些数_【每天15分钟,5天学会NumPy】第1天:基本概念
1.NumPy 的家族 NumPy 是 SciPy 家族的一员,而且是最重要的成员.SciPy 家族(见下图)是一个专门应用于数学.科学和工程领域的开源的Python生态圈.NumPy 最初是 Sci ...
最新文章
- 人性漫画:打工与创业的残酷区别……
- JS基础篇--HTML DOM classList 属性
- javascript设计模式实践之模板方法--具有百叶窗切换图片效果的JQuery插件(二)...
- QT的QCameraInfo类的使用
- 一个关于winform多线程的教程(pdf)
- 四年级上册数学计算机笔记,四年级数学下册笔记整理
- wicket_Wicket模型的干净方法
- linux双括号文本比较,Linux Shell 双括号运算符使用
- 在Windows Mobile上隐藏你的应用程序
- 产品人的归宿 · 之 · 创业维艰
- 百度常用搜索语法 超详解
- windows10桌面_windows10 美化桌面加强能力
- 使用Axis2实现WebService的发布和调用
- IDE添加文件头@author信息
- 保利威视播放器函数接口汇总
- 计算机考研能换专业吗,考研调剂到材料专业,很后悔,还能转到计算机专业吗?...
- 打台球百发百中?油管博主球杆上“做手脚”
- (HTTP 503) (Request-ID: req-4f56de6f-d29c-4c44-aed3-e6ef8253384a)
- 《那些年啊,那些事——一个程序员的奋斗史》——25
- Touch in Android
热门文章
- 计算机公式or,【转载】 odds、OR和RR的计算公式和实际意义
- python程序打包成安卓app教程_Python打包方法基本应用方式介绍
- html页面怎么加向下滚动,如何使用jQuery向上或向下滚动页面到锚点?
- java值栈_Struts2学习笔记-Value Stack(值栈)和OGNL表达式
- 测试项目:车牌检测,行人检测,红绿灯检测,人流检测,目标识别
- Zookeeper分布式安装部署
- 【学习Android NDK开发】Type Signatures(类型签名)
- HTTP Authentication(HTTP认证)(转)
- 二十多岁不信,三十多岁却深信不疑的道理
- vue内引入语音播报功能