1 / 86

# 本节内容有难度，考试不做要求。但是某些学校的考研课要考。主要强调思想，程序不多说。 - PowerPoint PPT Presentation

I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.

## PowerPoint Slideshow about ' 本节内容有难度，考试不做要求。但是某些学校的考研课要考。主要强调思想，程序不多说。' - lara-love

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.

- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript

4.2.2堆分配存储表示

#include <iostream>

using namespace std;

struct SString//串

{

char *s;//存储串中字符

int str_len;

};

int strlen(SString s)//求串的长度

{

return s.str_len;

}

///

int str_assign(SString &s1,char *s2)

{

int len=strlen(s2);//假定s2的长度不会超过MAXSTRLEN

s1.str_len=len;

s1.s=new char[len+1];//第0个单元不用

for(int i=1;i<=len;i++)

s1.s[i]=s2[i-1];

return 1;

}

int str_insert(SString &s,int i,char a)//在串中插入一个字符

{

int len=strlen(s);

if(i<1 || i>len+1) return 0;//越界

char *temp=new char[len+1+1];//0单元不用，又增加一个

for(int j=1;j<=i-1;j++)

temp[j]=s.s[j];

temp[i]=a;

for(j=i+1;i<=len;j++,i++)

temp[j]=s.s[i];

s.str_len++;

delete []s.s;

s.s=temp;

return 1;

}

int str_copy(SString &s1,SString &s2)

{//将s2中字符串拷贝到s1中

char *temp=new char[s2.str_len];

//delete []s1.s;

//s1.s=temp;

for(int i=1;i<=strlen(s2);i++)

temp[i]=s2.s[i];

s1.str_len=s2.str_len ;

delete []s1.s;

s1.s=temp;

return 1;

}

void str_cat(SString &s0,SString s1,SString s2)

{//将s2连接到s1的后面,结果存放在s0中，若空间不够则截断

s0.s=new char[s1.str_len+s2.str_len+1];

//0单元不用

s0.str_len=s1.str_len+s2.str_len;

for(int i=1;i<=s1.str_len;i++)

s0.s[i]=s1.s[i];

for(int j=1;j<=s2.str_len;j++,i++)

s0.s[i]=s2.s[j];

}

int str_index(SString s,SString t,int pos)

{//从第pos个位置开始查找t在s中出现的第一个位置

if(pos<1) return 0;

int start=pos,end=s.str_len-t.str_len+1;

for(int i=start;i<=end;i++)

{

for(int j=1,k=i;j<=t.str_len;j++,k++)

{

if(s.s[k]!=t.s[j])

break;

}

if(j>t.str_len)return i;

}

return 0;

}

void print(SString &s)

{

for(int i=1;i<=strlen(s);i++)

cout<<s.s[i];

cout<<endl;

}

//////////

int main(int argc, char* argv[])

{

SString a,b;

str_assign(a,"abc");

str_assign(b,"def");

print(a);

print(b);

::str_insert(a,2,\'m\');

print(a);

::str_copy(a,b);

print(a);

str_assign(a,"aaa");

str_assign(b,"bbb");

print(a);print(b);

SString c;

str_cat(c,a,b);

print(c);

str_assign(a,"abcdefghijklmn");

str_assign(b,"defg");

print(a);

print(b);

cout<<str_index(a,b,1)<<endl;

return 0;

}

4.3 串的模式匹配算法

4.3.1 传统的模式匹配算法（前面已经介绍）

4.3.2 KMP算法

### KMP算法

j

a

a

c

a

b

a

a

b

a

b

c

a

c

c

a

a

b

i

2

4

a

0

a

1

2

b

1

1

3

a

c

6

3

a

7

1

5

2

b

8

c

2

Next[j]

i

j

a

a

c

a

b

a

a

b

a

b

c

a

c

c

a

a

b

i

2

4

a

0

a

1

2

b

1

3

1

a

3

6

c

a

1

7

5

2

b

8

2

c

Next[j]

j

a

a

c

a

b

a

a

b

a

b

c

a

c

c

a

a

b

i

2

4

a

0

a

1

2

b

1

3

1

a

3

6

c

a

1

7

5

2

b

8

2

c

Next[j]

j

a

a

c

a

b

a

a

b

a

b

c

a

c

c

a

a

b

i

2

4

a

0

a

1

2

b

1

1

3

a

c

6

3

a

7

1

5

2

b

8

c

2

Next[j]

j

a

a

c

a

b

a

a

b

a

b

c

a

c

c

a

a

b

i

2

4

a

0

a

1

2

b

1

1

3

a

c

6

3

a

7

1

5

2

b

8

c

2

Next[j]

j

a

a

c

a

b

a

a

b

a

b

c

a

c

c

a

a

b

i

2

4

a

0

a

1

2

b

1

1

3

a

c

6

3

a

7

1

5

2

b

8

c

2

Next[j]

j

a

a

c

a

b

a

a

b

a

b

c

a

c

c

a

a

b

i

2

4

a

0

a

1

2

b

1

1

3

a

c

6

3

a

7

1

5

2

b

8

c

2

Next[j]

j

a

a

c

a

b

a

a

b

a

b

c

a

c

c

a

a

b

i

2

4

a

0

a

1

2

b

1

1

3

a

c

6

3

a

7

1

5

2

b

8

c

2

Next[j]

j

a

a

c

a

b

a

a

b

a

b

c

a

c

c

a

a

b

i

2

4

a

0

a

1

2

b

1

3

1

a

3

6

c

a

1

7

5

2

b

8

2

c

Next[j]

j

a

a

c

a

b

a

a

b

a

b

c

a

c

c

a

a

b

i

2

4

a

0

a

1

2

b

1

1

3

a

c

6

3

a

7

1

5

2

b

8

c

2

Next[j]

j

a

a

c

a

b

a

a

b

a

b

c

a

c

c

a

a

b

i

2

4

a

0

a

1

2

b

1

1

3

a

c

6

3

a

7

1

5

2

b

8

c

2

Next[j]

j

a

a

c

a

b

a

a

b

a

b

c

a

c

c

a

a

b

i

2

4

a

0

a

1

2

b

1

1

3

a

c

6

3

a

7

1

5

2

b

8

c

2

Next[j]

j

a

a

c

a

b

a

a

b

a

b

c

a

c

c

a

a

b

i

2

4

a

0

a

1

2

b

1

1

3

a

c

6

3

a

7

1

5

2

b

8

c

2

Next[j]

j

a

a

c

a

b

a

a

b

a

b

c

a

c

c

a

a

b

i

2

4

a

0

a

1

2

b

1

1

3

a

c

6

3

a

7

1

5

2

b

8

c

2

Next[j]

j

a

a

c

a

b

a

a

b

a

b

c

a

c

c

a

a

b

i

2

4

a

0

a

1

2

b

1

3

1

a

3

6

c

a

1

7

5

2

b

8

2

c

Next[j]

p1p2…p(j-1)=s(i-j+1)….s(i-1)

p1p2….pk=s(i-k+1)….s(i) -------〉

p1p2….p(k-1)=s(i-k+1)….s(i-1)

p(j-k+1)….p(j-1)=p1….p(k-1)

### Next[j]的手工求法

#include "stdafx.h"

//

#include<iostream>

#include<vector>

#include<string>

using namespace std;

void get_next(string s,vector<int> &next)

{

next[1]=0;

for(int j=2;j<=next.size()-1;j++)

{

for(int k=j-1;k>1;k--)

{

if(s.substr(1,k-1).compare(s.substr(j-k+1,k-1))==0)

break;

}

if(k>1)next[j]=k;

else next[j]=1;

}

}

int main(int argc, char* argv[])

{

string s="\$abaabcac";

vector<int> next;

next.resize(s.size());

get_next(s,next);

for(int i=1;i<=next.size()-1;i++)

cout<<next[i]<<" ";

cout<<endl;

return 0;

}

“p1p2…p(k-1)”=”…p(j-1)”

“p1p2…p(k-1)pk”=”…p(j-1)pj”,则Next[j+1]=k+1=Next[j]+1.

### Next的求法

i

a

4

a

0

1

1

2

b

a

3

c

6

7

a

b

5

c

8

Next[j]

j

i

4

a

a

4

0

0

1

1

a

a

2

2

b

1

1

b

a

a

3

3

6

c

c

6

a

7

7

a

5

b

5

b

c

c

8

8

Next[j]

Next[j]

s2！=p1，并且j=1，所以Next[3]=j=1

j

i

4

a

a

4

a

0

1

a

1

0

2

2

b

b

1

1

a

3

3

1

a

1

6

c

6

c

7

a

a

7

5

b

b

5

8

c

8

c

Next[j]

Next[j]

j

i

4

a

a

4

a

0

1

1

a

0

2

b

b

1

2

1

3

1

a

a

3

1

6

c

c

6

7

a

7

a

5

b

5

b

8

c

c

8

Next[j]

Next[j]

S3==p1,所以

Next[4]=j+1=2

j

i

4

a

4

2

2

a

1

a

0

1

a

0

1

b

2

1

b

2

1

1

3

3

a

a

c

6

c

6

7

7

a

a

b

5

5

b

c

8

8

c

Next[j]

Next[j]

s4！=p2,所以回溯到next[j]=1

j

i

4

a

4

2

2

a

1

a

0

1

a

0

1

b

2

1

b

2

1

1

3

3

a

a

c

6

c

6

7

7

a

a

b

5

5

b

c

8

8

c

Next[j]

Next[j]

s4==p1,所以next[5]=j+1=2，i、j后移

j

i

4

a

a

2

2

4

1

0

0

1

a

a

b

1

2

2

1

b

a

a

1

1

3

3

6

c

c

6

a

a

7

7

2

b

5

2

5

b

8

8

c

c

Next[j]

Next[j]

s5==p2,所以next[6]=j+1=3，i、j后移

j

i

a

2

4

2

4

a

0

a

1

1

0

a

2

b

1

b

2

1

3

a

1

1

a

3

6

c

3

3

c

6

a

a

7

7

b

2

2

b

5

5

8

8

c

c

Next[j]

Next[j]

S6！=p3,所以回溯到next[3]=1，

j

i

a

2

4

2

4

a

0

a

1

1

0

a

2

b

1

b

2

1

3

a

1

1

a

3

6

c

3

3

c

6

a

a

7

7

b

2

2

b

5

5

8

8

c

c

Next[j]

Next[j]

S6！=p1,所以next[7]=j=1

j

i

a

2

a

4

2

4

0

1

1

a

a

0

2

1

b

b

1

2

3

a

1

a

1

3

c

3

6

c

3

6

7

1

7

a

a

1

2

b

5

2

b

5

c

8

8

c

Next[j]

Next[j]

S7==p1,所以next[8]=1+1=2

j

i

4

a

2

4

2

a

1

0

1

0

a

a

2

2

1

b

b

1

3

1

3

a

a

1

6

3

3

6

c

c

1

7

a

7

a

1

5

b

5

2

b

2

2

c

8

c

8

2

Next[j]

Next[j]

void get_next(string s,vector<int> &next)

{

next[1]=0;

next[2]=1;

int i,j;

i=2;

j=1;

while(i<=next.size()-2)

{

if(j==1)

{

if(s[i]!=s[j])

{

next[i+1]=j;

i++;

continue;

}

}

if(s[i]==s[j])

{

next[i+1]=j+1;

i++;j++;

}

else

{

j=next[j];

}

}

}