串与数组的学习Word格式文档下载.docx
- 文档编号:16234870
- 上传时间:2022-11-21
- 格式:DOCX
- 页数:32
- 大小:545.09KB
串与数组的学习Word格式文档下载.docx
《串与数组的学习Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《串与数组的学习Word格式文档下载.docx(32页珍藏版)》请在冰豆网上搜索。
这种存储方式称为串的堆存储方式。
二,串的链式存储
串的链式存储结构简称链串。
由于串结构的特殊性,即结构中每个数据元素是一个字符,则用链表存储串值时,存在一个“结点大小”的问题。
即每个结点可以存放一个字符,也可以存放多个字符。
串的链式存储结构对某些串操作,比如联接操作等有一定的方便之处,但是总的来说不如顺序串灵活,它占用的存储空间大并且操作复杂。
链串的存储结构用类型描述如下:
typedefstructnode{
chardata;
//每个结点存1个字符
structnode*next;
//指向后面结点的指针域
}LinkStrNode,*LinkString;
//定义一个指向链串的指针
三,串运算的一些实现
1),求串长
intStrLength(SeqString*s)
{
returns->
length;
}
2),比较串的大小
intStrCompare(SeqString*s1,SeqString*s2)
{///使用串s1的长度减去串s2长度的差,可比较大小
inti;
i=s1->
length-s2->
returni;
3),串联接
SeqString*StrConcat(SeqString*s1,SeqString*s2)
{//该函数将串s2复制到串s1的末尾,串s1的长度为两串长度之和,还有置放一个结束标志。
//函数要返回一个指向串s1开始处的指针
for(inti=0;
i<
s2->
i++)
s1->
ch[s1->
length+i]=s2->
ch[i];
//逐个字符输入联接
length=s1->
length+s2->
//长度改变
length]='
;
//置结束符
returns1;
4),串复制
SeqString*StrCopy(SeqString*s1,SeqString*s2)
{//该函数将串s2复制到串s1中,覆盖原来s1中的内容,s1中的内容是已复制的字符串s2的内容。
//其长度是原来s2的长度,最后要返回一个指向s1的指针。
ch[i]=s2->
//逐个字符输入
length=s2->
//长度改变,使用s2的长度
5),字符查询定位
intStrFristIndex(SeqString*s,charc)
{//在串s中查找字符c.用字符变量c与字符串s中每一个字符进行比较,没查到或没
//查完时继续查,查到后记下第一次出现的位置。
若找到,则返回该位置,否则返回-1.
for(i=0;
(i<
s->
length)&
&
(s->
ch[i]!
=c);
i++);
//循环体为空
if(i>
=s->
length)
i=-1;
else
i=i+1;
//从0开始,查到退出,要用i+1
6),字符串插入
voidStrInsert(SeqString*s1,SeqString*s2,inti)
intn,m,j;
n=s1->
m=s2->
if((i<
0)||(i>
n))
printf("
No.\n"
);
else{
length=m+n;
for(j=n;
j>
=i;
j--)//后移m个位置
ch[j+m]=s1->
ch[j];
for(j=i;
j<
i+m;
j++)//插入m个字符
ch[j]=s2->
ch[j-i];
}
7),字符串删除
voidStrDelete(SeqString*s,inti,intj)
intk,n;
n=s->
else{
for(k=i;
k<
i+j;
k++)//从后向前覆盖
ch[i]=s->
ch[k+j];
length=n-j;
//改变字符串长度
ch[s->
//加结束符号
8),取子串
intGetSubStr(SeqString*s1,SeqString*s2,inti,intj)
intsub1;
if((i+j)>
return1;
//不能取出,返回1
sub1=0;
while(sub1<
j){//符合条件,取字符
ch[sub1]=s1->
ch[i-1];
///从s1中取字符到s2中
i++;
sub1++;
//指针递增
length=sub1;
ch[sub1]='
//运算结果是字符串s2,s2置结束符
return0;
//能取出,返回0
-------------------------------------------------程序实现-------------------------------------------------------
1,使用顺序串,生成一个字符串
编程实现:
#include<
stdio.h>
#defineMaxSize100
voidCreateStr(SeqString*v)
scanf("
%s"
v->
ch);
MaxSize;
i++){
%c"
ch[i]);
if(v->
ch[i]=='
)
break;
v->
length=i;
\nLength=%d.\n"
length);
intmain()
SeqStringsy;
CreateStr(&
sy);
-----------------------------------------------------------------------------------------------------------------------------
串替换。
设串S,子串T,子串V,实现子串V替代所有主串S中出现的和子串T相等的不重叠的子串。
算法思想:
1),首先要在主串中查找出与子串T相等的子串,因此可以进行求子串定位;
2),找出与子串T相等的所有子串的每一个开始位置,然后再依次用子串V做相应替换。
3),由于子串T与子串V的长度不同,要改变原串S的长度。
4),如扫描完主串S的全部字符,未找到与子串相等的子串,则主串保持原样,不做任何替换。
*/
#defineMaxSize50
SeqStringS,T,V;
voidCreateStr(SeqString*v){
v->
//printf("
voidStrReplace(){
inti,j,k,n,m;
S.length;
i++)
for(j=i,k=0;
S.ch[i]==T.ch[k];
j++,k++){
if(k==T.length-1)
if(V.length<
=T.length){
for(n=i,k=0;
V.length;
n++,k++)
S.ch[n]=V.ch[k];
S.length=S.length-T.length+V.length;
i=n;
m=T.length-V.length;
if(m!
=0)
for(;
n<
n++)
S.ch[n]=S.ch[n+m];
}else{
m=V.length-T.length;
S.length=S.length+V.length-T.length;
for(n=S.length;
n>
i;
n--)
S.ch[n+m-1]=S.ch[n-1];
for(k=0;
k++,n++){
k=%dn=%d"
k,n);
//outLin(S);
}//outLin(S);
voidPrintStr(SeqStrings){
intn=s.length;
s.length;
s.ch[i]);
\n"
intmain(){
S);
T);
V);
StrReplace();
PrintStr(S);
}//这个程序没有写正确,改正中.....
模式匹配
在字符串t中查找子串p时,求第一次匹配的序号
假设t和p是两个给定的串,在t中寻找与p相同的子串的过程称为模式匹配。
实现这个模式匹配的简单算法(BF)需要进行n-m+1次匹配。
字符串匹配的朴素算法!
stdlib.h>
string.h>
ctype.h>
intsimp(char*t,char*p)
intm,n,i,j,bl;
n=strlen(t);
m=strlen(p);
i=0;
bl=1;
while((i<
n-m)&
(bl!
=0)){//从第一个查询,子串是否在主串中
j=0;
while((j<
=m-1)&
(p[j]==t[i+j]))
j++;
//若第一个相同,可继续查找,否则下一轮继续查
if(j<
=m-1){//若未查到,继续查找
}else
bl=0;
//查到bl=0
if(bl==0)//查到返回首字符所在位置
returni+1;
intk;
charstr1[]="
adedefghdefjik"
charstr2[]="
def"
k=simp(str1,str2);
k=%d\n"
k);
我们用结构体这样实现:
voidcreate(SeqString*v){
v->
intBF(SeqStrings,SeqStringt){
n=s.length;
m=t.length;
=0)){
(t.ch[j]==s.ch[i+j]))
=m-1){
i++;
if(bl==0)
SeqStrings,t;
create(&
s);
t);
intk=BF(s,t);
k=%d.\n"
串的模式匹配的改进算法
KMP算法是一种改进的字符串匹配算法,由D.E.Knuth与V.R.Pratt和J.H.Morris同时发现,因此人们称它为克努特—莫里斯—普拉特操作(简称KMP算法)。
KMP算法的核心思想是利用已经得到的部分匹配信息来进行后面的匹配过程。
用next[i]这个数组来存储当模式串的第i位比较出现不匹配时模式串的从哪里开始比较!
如果next[i]=-1代表模式串的第一个与目标串的下一个比较!
计算前缀Next[i]的值:
令next[0]=-1。
从next[1]开始,每求一个字符的next值,就看它前面是否有一个最长的"
字符串"
和从第一个字符开始的"
相等(需要注意的是,这2个"
不能是同一个"
)。
如果一个都没有,这个字符的next值就是0;
如果有,就看它有多长,这个字符的next值就是它的长度。
计算修正后的Nextval[i]值:
令nextval[0]=-1。
从nextval[1]开始,如果某位(字符)与它next值指向的位(字符)相同,则该位的nextval值就是指向位的nextval值(nextval[i]=nextval[next[i]]);
如果不同,则该位的nextval值就是它自己的next值(nextvalue[i]=next[i])。
举个例子:
next[0]=-1;
定值。
next[1]=0;
s[1]前面没有重复子串。
next[2]=0;
s[2]前面没有重复子串。
next[3]=0;
s[3]前面没有重复子串。
next[4]=1;
s[4]前面有重复子串s[0]='
a'
和s[3]='
。
next[5]=2;
s[5]前面有重复子串s[01]='
ab'
和s[34]='
next[6]=3;
s[6]前面有重复子串s[012]='
abc'
和s[345]='
next[7]=4;
s[7]前面有重复子串s[0123]='
abca'
和s[3456]='
nextval[0]=-1;
nextval[1]=0;
s[1]!
=s[0],nextval[1]=next[1]=0。
nextval[2]=0;
s[2]!
=s[0],nextval[2]=next[2]=0。
nextval[3]=-1;
s[3]==s[0],nextval[3]=nextval[0]=-1。
nextval[4]=0;
s[4]==s[1],nextval[4]=nextval[1]=0。
nextval[5]=0;
s[5]==s[2],nextval[5]=nextval[2]=0。
nextval[6]=-1;
s[6]==s[3],nextval[6]=nextval[3]=-1。
nextval[7]=4;
s[7]!
=s[4],nextval[7]=next[7]=4。
说实话,这个算法只有慢慢滴慢慢滴消融到记忆的长河中,才好用!
程序实现:
/*
样例输入:
3
143
adedefghdefijk
def
348
efhigkhgkmnghimnsghigkmnsghinegphq
ghigkmns
7710
uioqerqprwtrpetphasfdpahapwehrfdshpaefhprewpqwieurptqweryptrewptfahsfdajfdafj
hpaefhprew
样例输出:
4
18
34
#include<
iostream>
cstdio>
cstring>
#defineM10001
usingnamespacestd;
chars[M*100],t[M];
intnext[M];
//得到next数组,下标均从1开始
voidget_next(intm)
inti=1,j=0;
next[1]=0;
while(i<
=m){//while(t[i]!
='
if(j==0||t[i]==t[j]){
++i;
++j;
next[i]=j;
j=next[j];
intkmp(intn,intm)
inti=0,j=1;
get_next(m);
=n&
j<
=m){
if(!
j||s[i]==t[j]){
if(j>
m)
returni-m;
return-1;
//找不到则返回-1
inttes,m,n,i;
%d"
&
tes);
while(tes--){
scanf("
%d%d"
n,&
m);
s+1);
t+1);
printf("
%d\n"
kmp(n,m));
-------以下这个C++的程序也很值得称道的:
靓靓(不是我写的,改写)
string>
//计算next数组
staticint*__getNextofString(string&
p)
intsize=p.size();
int*next=newint[size+1];
inti,j;
i=1;
j=0;
while(i<
size)
{
if(j==0||p[i-1]==p[j-1]){
++i;
next[i]=j;
}
else
j=next[j];
returnnext;
staticint__findSubString(conststring&
t,conststring&
p,int*next,intindex=1){//查找
inttlen,plen;
tlen=t.size();
plen=p.size();
i=index;
j=1;
=tlen&
=plen){
if(j==0||t[i-1]==p[j-1])
{++i;
if(j>
plen)
retur
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数组 学习
![提示](https://static.bdocx.com/images/bang_tan.gif)