Loading [MathJax]/jax/output/CommonHTML/fonts/TeX/AMS-Regular.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >数据结构:线性结构

数据结构:线性结构

作者头像
ttony0
发布于 2022-12-26 10:51:04
发布于 2022-12-26 10:51:04
1.1K00
代码可运行
举报
运行总次数:0
代码可运行

一、Ackerman函数

Ackerman函数有A(n,m)有两个独立的整变量m0,n0,其定义如下

A(1,0)=2

A(0,m)=1,m0

A(n,0)=n+2,n2

根据定义式可以简单地写出它的递归代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int Ackerman(int n,int m){
  if(n<0 || m<0)return -1;	//无定义
	if(n==1 && m==0)return 2;
	if(n==0)return 1;
	if(m==0)return n+2;
  return Ackerman(Ackerman(n-1,m),m-1);
}

字符串

一、子串定位:KMP算法

1、算法思路

定义主串串为目标串S,子串为模式串P。在朴素模式匹配算法中,每次匹配不成功之后,模式串只是向后移动1位,即存在大量回溯;我们可以利用部分匹配的结果,让模式串在不匹配时可以往后移动尽量远的距离,减少匹配次数。

KMP算法只针对模式串进行分析,对模式串求出数组Next[j],在模式串第j位比较失败之后利用Next[j]得到往后移几位。

Next数组的实质是找模式串中的最长相同的前缀和后缀(前缀不包括最后一个字符,后缀不包括第一个字符),实际意义为k=模式串第j位前的子串最长相同的前缀和后缀的长度+1,即将子串移动至第k位再次进行比较,如图所示。

j

1

2

3

4

5

6

7

S

a

b

a

c

a

b

c

Next[j]

0

1

1

2

1

2

3

NextVal[j]

0

1

0

2

0

1

3

根据上式,假设我们已经求出了next[j]数组,再将下标j按照C++的规则从0开始,就可以得到KMP算法的基本代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int KMP(string s,string t){
	int i=0,j=0;
	int n=s.size(),m=t.size();
	while(i<n && j<m){
		if(j==-1 || s[i]==t[j]){
			i++;
			j++}
		else{
			j=next[j];
		}
	}
	if(j==m)return i-j;
	else return -1;
}

2、Next数组

我们的代码依赖了数组next[j],next数组的定义上面已经说明,但它的求法更加精妙,首先我们贴出它的代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/*
这个算法得出的next[i]为最长前后缀的长度,即代表最长前缀的下一个字符的位置
*/
void getNext(string s){
    next[0]=-1;
    next[1]=0;
    int i=2;//i代表填充next数组的i位置
    int cn=0;//cn始终代表字符串i-1位置前面的字符串的最长前缀的下一个字符的位置
    while (i<s.size()){
  	  if(s[i-1]==s[cn])//如果字符串i-1位置上的字符等于字符串cn位置上的字符的话,直接在next[i]的基础上加1即可
  	 	 next[i++]=++cn;
 	  else if(cn>0)//这个条件满足,说明可以往前跳,让cn往前跳
         cn=next[cn];
  	  else
  	 	 next[i++]=0;//字符串i位置前面的字符串没有前缀
  	  }
}

以abacabc为例:

  1. next[0]=-1
  2. next[1]=0
  3. i=2,cn=0,s[1]!=s[0],且cn==0,next[2]=0
  4. i=3,cn=0,s[2]==s[0],next[3]=++cn=1
  5. i=4,cn=1,s[3]!=s[1],且cn>0,cn=next[1]=0,重复一次循环,i=4,cn=0,s[3]!=s[0],next[4]=0
  6. i=5,cn=0,s[4]==s[0],next[4]=++cn=1
  7. i=6,cn=0,s[5]==s[0],next[5]=++cn=2

比较难理解的为cn=next[cn]这段代码,实际为将当前前缀长度跳回到cn这一字符的最长前缀,由于next[cn]的前后缀必相同,只需继续再次比较cn与i-1的字符即可,如图:

3、NextVal数组

观察s[4],当它不匹配时,按照next行回溯到s[1]也为字母a,这时再匹配a是徒劳的,因为已知a不匹配,所以就继续退回到s[1]字母a的next[1]=0。为了进行优化,就有了nextval:

若要求nextval[i],将next[i]的值对应的位的值与i的值进行比较: 若相等,nextval[i]=nextval[ next[i] ]; 若不相等,则nextval[i]=next[i]。

代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int get_nextval(string T){
//求模式串T的next函数修正值并存入数组nextval。
	for(int i=1;i<T.size();i++){
		if(T[next[i]] == T[i])
			nextval[i]=nextval[next[i]];
		else nextval[i]=next[i];
	}
}//get_nextval

数组

一、快速转置算法

1、稀疏矩阵的三元组存储

矩阵本身的数据:行、列、元素个数

矩阵元素的数据:行序号、列序号、元素值

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
struct Triple{ 
  int I,j;
  elementtype e;
};	//矩阵元素

struct TSMatrix{
	Triple data[Max+1];
  int mu,nu,tu;
}; //矩阵

而由于稀疏矩阵的数据排列是行对齐的(根据行的顺序排列),所以如果进行转置,需要重新对数据进行排列,快速转置则是在尽可能少次数地遍历矩阵的情况下完成转置。

2、算法思路

首先我们给出一个5×5的稀疏矩阵:

数组data

5/行

5/列

6/元素个数

0

1

1

3

1

1

5

7

2

2

3

-1

3

3

1

-1

4

3

2

-2

5

5

4

2

经过转置后,它的排列需要是这样:

数组data

5/行

5/列

6/元素个数

0

1

1

3

1

1

3

-1

2

2

3

-2

3

3

2

-1

4

4

5

2

5

5

1

7

为了预先确定矩阵M中的每一列的第一个非零元素在数组中的位置,需要先求得矩阵M中的每一列中非零元素的个数。为此,需要设置两个一维数组num[n]和cpot[n],其中n为矩阵列数

  • num[]:储存每一列非零元素的个数
  • cpot[]:储存每一列的第一个非零元素在数组中的位置

通过这两个数组,我们可以在仅遍历数组两次的情况下完成矩阵的转置:

  1. 在第一次遍历时,通过对列的遍历,我们可以得到num[]。
  2. cpot[1]=0 cpot[col]=cpot[col-1]+num[col-1]
  3. 第二次遍历即可根据cpot开始元素的转置:每读取一个元素,若列为i,则将行列调换,放入新的data[cpot[data[i].j]]]之中,并将cpot[i]+1。
  4. 完成第二次遍历,完成算法。

3、代码实现

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
TSMatrix trans(TSMatrix mat){
	TSMatrix nmat;
	nmat.mu=mat.nu;
	nmat.nu=mat.mu;
	nmat.tu=mat.tu;
	int num[10]={0};
	int cpot[mat.nu];
	for(int i=0;i<mat.tu;i++){
		num[mat.data[i].j]++;
	}
	cpot[0]=0;
	for(int i=1;i<mat.nu;i++){
		cpot[i]=cpot[i-1]+num[i-1];
	}
	for(int i=0;i<mat.tu;i++){
		nmat.data[cpot[mat.data[i].j]].I=mat.data[i].j;
		nmat.data[cpot[mat.data[i].j]].j=mat.data[i].I;
		nmat.data[cpot[mat.data[i].j]].e=mat.data[i].e;
		cpot[mat.data[i].j]++;
	}
	return nmat;
}

二、求杨辉三角系数

1、数学模型

杨辉三角是二项式系数在三角形中的一种几何排列,即我们熟知的二项式系数(a+b)n=C0nan+C1nan1b1++Cnnbn中的Ckn

如图,对于n次二项式,设第一行为n=0的系数,则n次二项式共有n+1个系数,设为0~n。

那么,我们可以发现,对于每一个n,an[0]=an[n]=1,且对于0<k<nan[k]=an1[k1]+an1[k]

2、代码实现

这样一来,建立一个数组进行递归计算,可以简单的求出n次二项式的二次项系数。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
void coff(int *a,int n){ //arr的大小为n+1
	if(n==1){
		a[0]=a[1]=1;
	}
	else{
		coff(a,n-1);
		a[n]=1;
		for(int i=n-1;i>0;i--){ //从最后一个开始,可以直接修改数组内容且不影响计算
			a[i]=a[i]+a[i-1];
		}
	}
}

3、测试函数

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#define N 10
int arr[N+1];
 
int main()
{
   	coff(arr,N);
		for(int i=0;i<=N;i++){
			cout<<arr[i]<<endl;
		} 
    return 0;
}

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-12-27 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
【数据结构】您有一份KMP算法教学已到账,请注意查收!!!
在上一篇内容中,我们详细介绍了朴素模式匹配算法及其实现。朴素模式匹配算法简单的理解就是将主串中以每一个位序上的元素为开头的子串与模式串进行匹配,直到匹配成功,或者匹配完主串中的所有可能的子串。
蒙奇D索隆
2024/09/07
1160
【数据结构】您有一份KMP算法教学已到账,请注意查收!!!
数据结构_KMP算法
在此处,失配了,所以要进行回溯,i的初始位置变成第二个元素位置,j的初始位置变成第一个元素位置,再进行匹配
用户10551528
2023/05/09
2180
数据结构_KMP算法
【算法】BF、KMP算法及OJ题
什么是BF算法❓ BF算法,即暴力(Brute Force)算法,是普通的模式匹配算法,BF算法的思想就是将目标串S的第一个字符与模式串T的第一个字符进行匹配,若相等,则继续比较S的第二个字符和 T的第二个字符;若不相等,则比较S的第二个字和T的第一个字符,依次比较下去,直到得出最后的匹配结果。BF算法是一种蛮力算法。 对于BF算法而言,如果匹配到不相等的,则模式串T要回到第一个字符。而KMP则会通过next数组回退到特定的位置。后面会展开说明。
平凡的人1
2022/11/15
5850
【算法】BF、KMP算法及OJ题
【数据结构】串代码实现
目录 串 串_String.c #include "string.h" #include "stdio.h" #include "stdlib.h" #include "math.h" #include "time.h" #define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0 #define MAXSIZE 40 /* 存储空间初始分配量 */ typedef int Status; /* Status是函数的类型,
CtrlX
2022/11/18
4410
数据结构实验之数组三:快速转置(SDUT 3347)
转置运算是一种最简单的矩阵运算,对于一个m*n的矩阵M( 1 = < m < = 10000,1 = < n < = 10000 ),它的转置矩阵T是一个n*m的矩阵,且T( i , j )=M( j , i )。显然,一个稀疏矩阵的转置仍然是稀疏矩阵。你的任务是对给定一个m*n的稀疏矩阵( m , n < = 10000 ),求该矩阵的转置矩阵并输出。矩阵M和转置后的矩阵T如下图示例所示。
Lokinli
2023/03/09
4170
数据结构实验之数组三:快速转置(SDUT 3347)
2024重生之回溯数据结构与算法系列学习(12)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丟脸好嘛?】
假设有串 T = '', S = 'iPhone 14 Pro Max?', W = 'Pro'
盛透侧视攻城狮
2024/10/22
910
2024重生之回溯数据结构与算法系列学习(12)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丟脸好嘛?】
数据结构(6):串(下)
子串的定位操作通常称为串的模式匹配,它求的是子串(常称模式串)在主串中的位置。下面给出一种不依赖于其他串操作的暴力匹配算法。
不可言诉的深渊
2021/07/01
5620
【数据结构】串与数组
文章目录 4. 串与数组 4.1 串概述 4.2 串的存储 4.3 顺序串 4.3.1 算法:基本功能 4.3.2 算法:扩容 4.3.3 算法:求子串 4.3.4 算法:插入 4.3.5 算法:删除 4.3.6 算法:比较 4.4 模式匹配【难点】 4.4.1 概述 4.4.2 Brute-Force算法:分析 4.4.3 Brute-Force算法:算法实现 4.4.4 KMP算法:动态演示 4.4.5 KMP算法:求公共前后缀 next数组 -- 推导 4.4.6 KMP算法:求公共前后缀 next数
陶然同学
2023/02/26
4K0
【数据结构】串与数组
《王道》数据结构笔记整理2022级_数据结构笔记整理
1.数据:数据是信息的载体,是描述客观事物属性的数、字符以及所有能输入到计算机中并被程序识别和处理的符号的集合。
全栈程序员站长
2022/09/22
3.1K0
《王道》数据结构笔记整理2022级_数据结构笔记整理
数据结构第四次实验 矩阵快速转置与矩阵加法
#include <bits/stdc++.h> using namespace std; struct xyz { int i,j; int v; }Triple; struct xsjz{ // 存储系数矩阵 xyz data[100]; int mu,nu,tu; }TsMatrix; int oder[10][3] = {{1,2,12},{1,3,9},{3,1,-3},{3,6,14},{4,3,24},{5,2,18},{6,1,15},{6,4,-7},{7,2,
用户2965768
2018/12/24
5030
数据结构试题库答案算法设计题
算法设计题(10分) (1)阅读下列递归算法,写出非递归方法实现相同功能的C程序。 void test(int &sum) { int x; scanf(x); if(x=0) sum=0 el
企鹅号小编
2018/01/09
1.5K0
数据结构试题库答案算法设计题
【数据结构】这里有一份KMP算法优化的详细攻略,不要错过哦!!!
在上一篇内容中我们详细介绍了KMP算法的基础知识点,相信大家在阅读完后应该对前缀、后缀、PM值、next数组这些基本概念有了一个初步的了解。但是在上一篇内容中我们对KMP算法的介绍还不够完整,遗留下来了两个问题:
蒙奇D索隆
2024/09/07
1380
【数据结构】这里有一份KMP算法优化的详细攻略,不要错过哦!!!
你所不知道的 KMP 冷知识
KMP算法由D.E.Knuth,J.H.Morris和V.R.Pratt提出的,因此人们称它为克努特—莫里斯—普拉特操作(简称KMP算法)。
ACM算法日常
2021/08/10
8780
漫画:什么是KMP算法?
在字符串匹配算法的前两讲,我们分别介绍了暴力算法BF算法,利用哈希值进行比较的RK算法,以及尽量减少比较次数的BM算法。
博文视点Broadview
2020/06/12
3920
漫画:什么是KMP算法?
重学数据结构(五、串)
串(string)(或字符串)是由零个或多个字符组成的有限序列,其中每个字符都来自某个字符表( Alphabet) Σ,比如 ASCII 字符集或 Unicode 字符集。 一般记为:
三分恶
2020/09/18
6490
一文帮你搞懂 | 串的模式匹配-朴素匹配和KMP算法及优化
 我们看看当我进行完前面的操作后,是否需要继续重i = 2, j = 1开始看起呢
莫浅子
2022/11/18
6680
一文帮你搞懂 | 串的模式匹配-朴素匹配和KMP算法及优化
数据结构——全篇1.1万字保姆级吃透串与数组(超详细)
 行序:使用内存中一维空间(一片连续的存储空间),以行的方式存放二维数组。先存放第一行,在存放第二行,依次类推存放所有行。
陶然同学
2023/02/27
1.9K0
数据结构——全篇1.1万字保姆级吃透串与数组(超详细)
KMP算法
一个文本串$S$(主串)和一个模式串$P$,求$P$在$S$中出现的位置,或者$P$在$S$中出现的次数,等等问题。
xiaohejun
2020/02/18
5290
稀疏矩阵转置多种算法详解
这次博文写的有点长,因为我得构思,所以今天晚上(11.10)写一点,另外还有个重要的任务,因为再过40分钟就是剁手节了,过了今晚我不止是一个光棍,更是一个穷光棍、、、、我该怎么办。。。求拦截。
全栈程序员站长
2022/06/25
1.4K0
稀疏矩阵转置多种算法详解
【算法】----BF算法&KMP算法
打开我们浏览器的搜索框,输入你想的这个词,然后点击Enter。浏览器就会自动搜索与该词匹配的内容。
Skrrapper
2024/06/18
1200
【算法】----BF算法&KMP算法
推荐阅读
相关推荐
【数据结构】您有一份KMP算法教学已到账,请注意查收!!!
更多 >
LV.0
这个人很懒,什么都没有留下~
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验