数据结构串实验报告

合集下载

【精品】数据结构串实验报告

【精品】数据结构串实验报告

【精品】数据结构串实验报告
(仅校内可用)
本次实验是基于数据结构串的相关知识,设计、实现及实验关于串的操作,并要求我们编写综合性实验报告。

1、实验目的是了解串结构及其实现方法,并能够用有限的时间内完成实验。

2、实验要求:
(1)实现关于串的一组基本操作
(2)实现串的模式匹配算法
3、实验的进度:
(1)完成程序的设计,要求建立合理的数据结构,编写部分重要算法,调试程序;
(2)设计一组完整的数据,并完成所设计程序的测试;
(3)对串模式匹配算法和高效率算法的效率、正确性进行测试;
(4)完成实验总结,参加试验验收。

4、实验结果:
(1)建立了串的节点数据结构,并编写相关操作算法,经测试结果显示,程序的实现能做到正确、有效的运行;
(2)完成对串模式匹配算法和高效率算法的测试,匹配算法水平介于暴力及KMP算法之间,效率较高;高效率算法在重复部分采用滑动窗口技术,同时避免了重复移动结点带来的时间开销,效率较高且正确性得到了优化;
(3)完成了实验总结,并得出本次实验的结论:实现串的模式匹配算法和高效率算法能够较好地实现串的基本操作,同时具有较高的效率;
最后,在实验过程中,我收获颇丰,加深了对串结构及实现方法的理解,使我对数据结构有了更全面的认识。

数据结构串的基本操作及应用实验报告

数据结构串的基本操作及应用实验报告

实验日期2010.5.10 教师签字成绩实验报告【实验名称】第四章串的基本操作及应用【实验目的】1、熟悉将算法转换成程序代码的过程。

2、了解串的逻辑结构特性,熟练掌握串顺序存储结构的C 语言描述方法。

3、熟练掌握串的基本操作:求长度、串的连接、插入、删除等,掌握串的存取特性。

【实验原理】1.串可以可以有三种存储方式,分别为顺序存储、堆分配存储、链式存储,串的基本操作在这三种存储方式下操作。

2.串的模式匹配KMP算法在每一趟匹配过程中出现字符不等时,不需回溯指针,而是利用已经得到的部分匹配结果的结果将模式向右滑动尽可能远的一段距离,继续进行比较。

【实验内容】1.串的顺序存储表示及基本操作(插入、删除、求串长、合并连接串、求子串、串比较等)#include<stdio.h>#include<iostream.h>#include<malloc.h>#include<string.h>#define SIZE 20struct HString{char ch[SIZE];int length;};void StrInsert(HString &s,int pos,HString t){int i,j;if(pos<1||pos>s.length+1)cout<<"ERROR!";if(t.length){for(i=s.length-1;i>=pos-1;--i)s.ch[i+t.length]=s.ch[i];for(j=0;j<=t.length-1;j++)s.ch[pos-1+j]=t.ch[j];s.length+=t.length;}}void StrDelete(HString &s,int pos,int len){int i;int v=pos-1;if(pos<1||pos>s.length||len<0||len>s.length-pos+1)cout<<"ERROR!";for(i=pos+len-1;i<=s.length-1;i++)s.ch[v++]=s.ch[i];s.length-=len;}void StrAssign(HString &t,char chars[]){int i;char *c;for(i=0,c=chars;*c;++i,++c);if(!i){t.length=0;}else{for(int j=0;j<i;j++)t.ch[j]=chars[j];t.length=i;}}int StrLen(HString &s){return s.length;}int StrCompare(HString &s,HString t){for(int i=0;i<s.length&&i<t.length;i++){if(s.ch[i]!=t.ch[i])return (int)(t.ch[i]-s.ch[i]);}return s.length-t.length;}void Concat(HString &t,HString s1,HString s2){int i=s1.length+s2.length;for(i=0;i<s1.length;i++)t.ch[i]=s1.ch[i];t.length=s1.length+s2.length;for(i=s1.length;i<t.length;i++)t.ch[i]=s2.ch[i-s1.length];}int SubString(HString &sub,HString s,int pos,int len) {if(pos<1||pos>s.length||len<0||len>s.length-pos+1) {cout<<"ERROR!"<<endl;return 0;}if(!len){sub.length=0;}else{int i=len;for(i=0;i<len;i++)sub.ch[i]=s.ch[pos+i-1];sub.length=len;}}void Display(HString &t){for(int i=0;i<=t.length-1;i++)cout<<t.ch[i];cout<<endl;}void main(){int i;char s[20];do{cout<<"选择您要进行的串的基本操作:"<<endl;cout<<"1.插入"<<endl<<"2.删除"<<endl<<"3.串连结"<<endl<<"4.取子串"<<endl<<"5.串比较"<<endl<<"6.求串长"<<endl<<"7.结束"<<endl;cin>>i;switch(i){case 1:{HString s,t;int pos;cout<<"请输入串s:";cin>>s.ch;StrAssign(s,s.ch);cout<<endl;cout<<"请输入要插入的串t:";cin>>t.ch;StrAssign(t,t.ch);cout<<endl;cout<<"请输入你所要插入的位置:";cin>>pos;StrInsert(s,pos,t);cout<<"插入之后串变为:";Display(s);break;}case 2:{HString s;int pos,len;cout<<"请输入串s:";cin>>s.ch;StrAssign(s,s.ch);cout<<"请输入你所要删除串的首位置为:";cin>>pos;cout<<"请输入你需要删除的串的长度:";cin>>len;StrDelete(s,pos,len);cout<<"删除之后串变为:";Display(s);break;}case 3:{HString s1,s2,t;cout<<"请输入串s1:";cin>>s1.ch;StrAssign(s1,s1.ch);cout<<"请输入串s2:";cin>>s2.ch;StrAssign(s2,s2.ch);Concat(t,s1,s2);cout<<"s1与s2合并后的串为:";Display(t);break;}case 4:{HString sub,s;int pos,len;cout<<"请输入主串s:";cin>>s.ch;StrAssign(s,s.ch);cout<<"请输入所取原串的起始位置pos:";cin>>pos;cout<<"请输入子串的长度len:";cin>>len;SubString(sub,s,pos,len);cout<<"取出的子串为:";Display(sub);break;}case 5:{HString s,t;int value;cout<<"请输入串s:";cin>>s.ch;StrAssign(s,s.ch);cout<<"请输入串t:";cin>>t.ch;StrAssign(t,t.ch);value=StrCompare(s,t);if(value>0) cout<<"串s大于串t"<<endl;else if(value==0) cout<<"串s等于串t"<<endl;else cout<<"串s小于串t"<<endl;cout<<endl;break;}case 6:HString s;char *chars;int val;cout<<"请输入串s:";cin>>s.ch;StrAssign(s,s.ch);val=StrLen(s);cout<<"串的长度为:"<<val<<endl;break;case 7:cout<<"操作结束!"<<endl;break;default:cout<<"输入错误!请重新输入!"<<endl;break;}}while(i!=7);}2.串的堆分配存储表示及基本操作(插入、删除、求串长、合并连接串、求子串、串比较等)#include<stdio.h>#include<iostream.h>#include<malloc.h>#include<string.h>struct HString{char *ch;int length;};void StrInsert(HString &s,int pos,HString t){int i,j;if(pos<1||pos>s.length+1)cout<<"ERROR!";if(t.length){s.ch=(char*)realloc(s.ch,(s.length+t.length)*sizeof(char));for(i=s.length-1;i>=pos-1;--i)s.ch[i+t.length]=s.ch[i];for(j=0;j<=t.length-1;j++)s.ch[pos-1+j]=t.ch[j];s.length+=t.length;}}void StrDelete(HString &s,int pos,int len){int i;int v=pos-1;if(pos<1||pos>s.length||len<0||len>s.length-pos+1)cout<<"ERROR!";for(i=pos+len-1;i<=s.length-1;i++)s.ch[v++]=s.ch[i];s.length-=len;}void StrAssign(HString &t,char *chars){int i;char *c;for(i=0,c=chars;*c;++i,++c);if(!i){t.ch=NULL;t.length=0;}else{t.ch=(char *)malloc(i*sizeof(char));for(int j=0;j<i;j++)t.ch[j]=chars[j];t.length=i;}}int StrLen(HString &s){return s.length;}int StrCompare(HString &s,HString t){for(int i=0;i<s.length&&i<t.length;i++){if(s.ch[i]!=t.ch[i])return (int)(t.ch[i]-s.ch[i]);}return s.length-t.length;}void Concat(HString &t,HString s1,HString s2){int i=s1.length+s2.length;t.ch=(char *)malloc(i*sizeof(char));for(i=0;i<s1.length;i++)t.ch[i]=s1.ch[i];t.length=s1.length+s2.length;for(i=s1.length;i<t.length;i++)t.ch[i]=s2.ch[i-s1.length];}int SubString(HString &sub,HString s,int pos,int len){if(pos<1||pos>s.length||len<0||len>s.length-pos+1){cout<<"ERROR!"<<endl;return 0;}if(!len){sub.ch=NULL;sub.length=0;}else{int i=len;sub.ch=(char *)malloc(i*sizeof(char));for(i=0;i<len;i++)sub.ch[i]=s.ch[pos+i-1];sub.length=len;}}void Display(HString &t){for(int i=0;i<=t.length-1;i++)cout<<t.ch[i];cout<<endl;}void main(){int i;char s[20];cout<<"选择您要进行的串的基本操作:"<<endl;do{cout<<"1.插入"<<endl<<"2.删除"<<endl<<"3.串连结"<<endl<<"4.取子串"<<endl<<"5.串比较"<<endl<<"6.求串长"<<endl<<"7.结束"<<endl;cin>>i;switch(i){case 1:{HString s,t;char a[20],b[20];char *sa,*sb;int pos;cout<<"请输入串s:";cin>>a;sa=a;StrAssign(s,sa);cout<<endl;cout<<"请输入要插入的串t:";cin>>b;sb=b;StrAssign(t,sb);cout<<endl;cout<<"请输入你所要插入的位置:";cin>>pos;StrInsert(s,pos,t);cout<<"插入之后串变为:";Display(s);break;}case 2:{HString s;char str[20];char *chars;int pos,len;cout<<"请输入串s:";cin>>str;chars=str;StrAssign(s,chars);cout<<"请输入你所要删除串的首位置为:";cin>>pos;cout<<endl;cout<<"请输入你需要删除的串的长度:";cin>>len;cout<<endl;StrDelete(s,pos,len);cout<<"删除之后串变为:";Display(s);break;}case 3:{HString s1,s2,t;char a[20],b[20];char *sa,*sb;cout<<"请输入串s1:";cin>>a;sa=a;StrAssign(s1,sa);cout<<"请输入串s2:";cin>>b;sb=b;StrAssign(s2,sb);Concat(t,s1,s2);cout<<"s1与s2合并后:";Display(t);break;}case 4:{HString sub,s;char a[20];char *sa;int pos,len;cout<<"请输入主串s:";cin>>a;sa=a;StrAssign(s,sa);cout<<"请输入所取原串的起始位置pos:";cin>>pos;cout<<"请输入子串的长度len:";cin>>len;SubString(sub,s,pos,len);cout<<"该子串为:";Display(sub);break;}case 5:{HString s,t;int value;char a[20],b[20];char *sa,*sb;cout<<"请输入串s:";cin>>a;sa=a;StrAssign(s,sa);cout<<"请输入串t:";cin>>b;sb=b;StrAssign(t,sb);value=StrCompare(s,t);if(value>0) cout<<"串s大于串t"<<endl;else if(value==0) cout<<"串s等于串t"<<endl;else cout<<"串s小于串t"<<endl;cout<<endl;break;}case 6:HString s;char str[20];char *chars;int val;cout<<"请输入串s:";cin>>str;chars=str;StrAssign(s,chars);val=StrLen(s);cout<<"串的长度为:"<<val<<endl;break;case 7:cout<<"操作结束!"<<endl;break;default:cout<<"输入错误!请重新输入!"<<endl;break;}}while(i!=7);3.KMP算法的C实现#include<iostream.h>#include<malloc.h>#include<string.h>struct HString{char *ch;int length;};void StrAssign(HString &t,char *chars){int i;char *c;for(i=0,c=chars;*c;++i,++c);if(!i){t.ch=NULL;t.length=0;}else{t.ch=(char *)malloc(i*sizeof(char));for(int j=0;j<i;j++)t.ch[j]=chars[j];t.length=i;}}void get_next(HString s,int next[]){int i,j;i=1;j=0;next[1]=0;while(i<s.length){if(j==0||s.ch[i-1]==s.ch[j-1]){i++;j++;next[i]=j;}else j=next[j];}for(i=1;next[i]!='\0';i++)cout<<next[i]<<" ";}int Index(HString s,HString t,int pos){int i=pos;int j=1;int next[20];get_next(t,next);while(i<=s.length&&j<=t.length){if(s.ch[i-1]==t.ch[j-1]||j==0){ ++i;++j;}else{j=next[j];}}if(j>t.length)return i-t.length;else return 0;}void Display(HString t){for(int i=0;i<t.length;i++)cout<<t.ch[i];cout<<endl;}void main(){ HString s,t;int pos,k;char a[20],b[20];char *sa,*sb;cout<<"请输入主串s:";cin>>a;sa=a;StrAssign(s,sa);cout<<"请输入模式串t:";cin>>b;sb=b;StrAssign(t,sb);cout<<"请输入起始位置pos:";cin>>pos;k=Index(s,t,pos);if(k==0)cout<<"匹配失败!"<<endl<<endl;else{cout<<"从第"<<k<<"个位置开始匹配"<<endl;Display(s);for(int i=1;i<k;i++)cout<<" ";Display(t);}}【小结讨论】1. 此程序关键在于位置查询,由于对C语言函数的陌生导致问题变的繁琐,自己的C语言水平有待提高。

串-数据结构实验报告

串-数据结构实验报告

三、.实习题 1. 将上述实例打入计算机,调试运行。 字符串常量的提供有多种手段。可以在定义串类型同时初始化串 值: char t[]="abc",*v="%%%"; 还可以使用语句gets(s)进行输入;也可以用scanf("%s",s)进行输入。 请你试着用不同的方法修改、调试、运行程序。 【源程序】: #include <stdio.h> #include <string.h> #include<stdlib.h> int index(char *s, char *t,int pos); void replace(char *s,char *t,char *v); void main() //主函数 { char *s,t[]="abc",*v="%%%"; s=(char *)malloc(100*sizeof(char)); printf("\n s=?"); scanf("%s",s); printf("\n s=%s\n",s); printf("\n t=%s v=%s\n",t,v); replace(s,t,v); /* 调用串置换函数 */ printf("\n\n new string=%s\n",s);
} end_main /* 串的置换,将主串s中的t串,置换为v串 */ void replace(char *s,char *t,char *v) { int i,j,k,po,sl,tl; sl=strlen(s); tl=strlen(t); printf("\n sl=%d tl=%d\n",sl,tl); po=0; while( po< sl-tl+1) { k=index(s,t,po); /* 调用串匹配函数 */ printf("\n k=%2d",k); if(k==-1) break; i=k-1; for(j=0;j<=tl-1;j++) { s[i]=v[j];i++;} po=k+tl; printf(" pos=%2d",po); } } /* replace */ /* 串匹配函数 */ /* 从主串s的第pos个字符开始查找子串t,函数结果是子串t在主 串s的pos开始之后首次出现的位置 */ int index(char *s, char *t, int pos) {int i,j,sl,tl; i=pos; j=1; sl=strlen(s); tl=strlen(t); while(i<=sl && j<=tl) if(s[i-1]==t[j-1]) {i++; j++; } else { i=i-j+1+1; j=1;} if(j>tl) return(i-tl); else return(-1); } /* index */ 程序运行截图如下

数据结构实验报告串

数据结构实验报告串

数据结构实验报告串《数据结构实验报告串》在数据结构课程中,实验报告是非常重要的一环。

通过实验报告,我们能够将课堂上学到的知识应用到实际中,加深对数据结构的理解和掌握。

本次实验报告串将介绍我们在数据结构实验中所进行的一系列实验,以及实验结果和分析。

实验一:数组和链表的比较在第一个实验中,我们对数组和链表进行了比较。

我们通过编写代码,分别实现了数组和链表的基本操作,包括插入、删除、查找等。

通过对比实验结果,我们发现在插入和删除操作中,链表的效率明显高于数组,而在查找操作中,数组的效率更高。

这说明在不同的场景下,数组和链表都有各自的优势和劣势。

实验二:栈和队列的应用在第二个实验中,我们学习了栈和队列的应用。

我们通过编写代码,实现了栈和队列的基本操作,并应用到实际问题中。

我们发现栈适合用于实现逆波兰表达式和括号匹配等问题,而队列适合用于实现广度优先搜索和模拟排队等问题。

这些实际应用让我们更加深入地理解了栈和队列的特点和用途。

实验三:树和图的遍历在第三个实验中,我们学习了树和图的遍历算法。

我们通过编写代码,实现了深度优先搜索和广度优先搜索算法,并应用到树和图的遍历中。

我们发现深度优先搜索适合用于解决迷宫问题和拓扑排序等问题,而广度优先搜索适合用于解决最短路径和连通性问题。

这些实验让我们更加深入地理解了树和图的遍历算法,以及它们在实际中的应用。

通过以上一系列实验,我们对数据结构的理论知识有了更深入的理解,同时也掌握了一些实际应用的技能。

实验报告串的编写过程也让我们更加熟练地掌握了数据结构的相关操作和算法。

希望通过这些实验,我们能够更好地应用数据结构知识,解决实际中的问题,提高编程能力和算法水平。

数据结构 串 实验报告

数据结构 串 实验报告

实验报告实验名称:串实验目的:(1)、熟悉C语言的上机环境,进一步掌握C语言的结构特点;(2)、掌握串的定义及C语言实现;(3)、掌握串的模式匹配及C语言实现;(4)、掌握串的各种基本操作;实验步骤:(1)、建立链串类型(2)、实现匹配过程中需考虑的链表的特征。

实验内容:4.一个字符串中的任意一个子序列,若子序列中各字符值均相同,则成为字符平台。

写一算法,输入任意以字符串S,输出S中长度最大的所有字符平台的起始位置及所含字符。

注意,最大字符平台有可能不止一个。

实验数据记录:(源代码及执行过程)#include<stdio.h>#include<stdlib.h>#define Maxsize 20#define n 100typedef struct Node{int element[Maxsize];int front;int rear;}Queue;int EnterQueue(Queue *Q,int x){if((Q->rear+1)%Maxsize == Q->front){printf("队列已满!\n");return 0;}Q->element[Q->rear] = x;Q->rear = (Q->rear+1)%Maxsize;return 1;}int DeleQueue(Queue *Q,int *x){if(Q->front == Q->rear){printf("队列为空!\n");return 0;}*x = Q->element[Q->front];Q->front = (Q->front+1)%Maxsize;return 1;}int Donull(Queue *Q){while(Q->front != Q->rear){Q->element[Q->front] = 0;Q->front = (Q->front+1)%Maxsize;}Q->front = Q->rear = 0;if(Q->front == Q->rear){return 1;}else{return 0;}}int main(void){char str[n];int i=0,j=1,k=1,ch,p=1,flag=1;Queue *Q;Q = (Queue *)malloc(sizeof(Queue));Q->front = Q->rear = 0;printf("请输入字符串:");gets(str);while('\0' != *(str+i)){ while(*(str+i+1) == *(str+i)){if(flag){p = i;flag = 0;}i++;j++;}if(flag){p = i;}if(j >= k){if(j > k){Donull(Q);k = j;}if(EnterQueue(Q ,j) == 0)break;if(EnterQueue(Q,p+1) == 0)break;if(EnterQueue(Q,*(str+i)) == 0)break;}j=1;i++;flag = 1;} while(Q->front < Q->rear){DeleQueue(Q,&j);DeleQueue(Q,&k);DeleQueue(Q,&ch);printf("%-10d",k);for(i = 0; i < j; i++){printf("%c",ch);}printf("\n");}printf("\n");system("pause");}。

数据结构实验报告串

数据结构实验报告串

数据结构实验报告串数据结构实验报告串一、引言数据结构是计算机科学的基础,它研究数据的组织、存储和管理方式。

在本次实验中,我们将学习和实践一些常见的数据结构,如链表、栈和队列。

通过实验,我们将深入了解这些数据结构的特点、优势和应用场景。

二、链表链表是一种常见的数据结构,它由一系列节点组成,每个节点包含数据和指向下一个节点的指针。

链表可以分为单向链表和双向链表两种类型。

在实验中,我们实现了一个简单的单向链表,并进行了一系列操作,如插入、删除和遍历。

通过实验,我们发现链表的插入和删除操作时间复杂度为O(1),这是因为链表的节点可以通过指针直接连接,而不需要移动其他节点。

然而,链表的缺点是访问节点的时间复杂度为O(n),因为我们需要从头节点开始遍历链表直到找到目标节点。

三、栈栈是一种后进先出(LIFO)的数据结构,它只允许在栈顶进行插入和删除操作。

在实验中,我们实现了一个简单的栈,并进行了一系列操作,如入栈、出栈和获取栈顶元素。

通过实验,我们发现栈的插入和删除操作时间复杂度为O(1),这是因为栈的元素只能在栈顶进行操作。

栈的应用场景很广泛,例如函数调用和表达式求值。

在函数调用中,每次函数调用时,会将函数的返回地址和局部变量等信息存储在栈中,以便函数执行完毕后可以返回到正确的位置。

四、队列队列是一种先进先出(FIFO)的数据结构,它允许在队尾插入元素,在队头删除元素。

在实验中,我们实现了一个简单的队列,并进行了一系列操作,如入队、出队和获取队头元素。

通过实验,我们发现队列的插入和删除操作时间复杂度为O(1),这是因为队列的元素只能在队头和队尾进行操作。

队列的应用场景很多,例如任务调度和消息传递。

在任务调度中,每个任务都会被加入到队列中,然后按照先后顺序执行,确保任务按照正确的顺序完成。

五、实验总结通过本次实验,我们深入了解了链表、栈和队列这些常见的数据结构。

我们学习了它们的特点、优势和应用场景,并通过实践掌握了它们的基本操作。

数据结构顺序串基本操作实验报告

数据结构顺序串基本操作实验报告

数据结构顺序串基本操作实验报告实验目的:1.掌握顺序串的定义和基本操作;2.掌握顺序串的插入、删除、查找等基本操作。

实验内容:实现顺序串的基本操作,包括串的初始化、插入、删除、查找、输出等操作,并通过实例测试验证操作的正确性。

实验原理:顺序串是一种以连续的存储空间来存储字符序列的数据结构。

在顺序串中,字符串的字符元素依次存储在一组连续的存储单元中,可以通过下标来访问和修改元素。

顺序串的基本操作包括初始化、插入、删除、查找等。

1.串的初始化:初始化一个空串,即将串的长度设置为0。

2.串的插入:在指定位置插入一个字符或字符串。

首先需要判断插入位置的合法性,即位置不能超过当前串的长度,并将插入位置后的元素后移一位,然后将要插入的元素放入指定位置。

3.串的删除:删除指定位置的字符或字符串。

首先需要判断删除位置的合法性,即位置不能超过当前串的长度,然后将删除位置后的元素前移一位。

4.串的查找:在串中查找指定字符或子串第一次出现的位置。

遍历串中的每个元素,检查是否与要查找的字符或子串相等,若相等则返回其位置。

5.串的输出:将串中的元素打印出来。

实验步骤:1.定义顺序串的数据结构。

使用数组来存储字符序列,并定义一个变量用于记录串的长度。

2.初始化一个空串。

将串的长度设置为0。

3.实现插入操作。

根据插入位置的合法性,判断是否需要进行插入操作。

如果插入位置超过了当前串的长度,则将元素插入到串末尾;否则,将插入位置后的元素后移一位,并将要插入的元素放入指定位置。

4.实现删除操作。

根据删除位置的合法性,判断是否需要进行删除操作。

如果删除位置超过了当前串的长度,则无需删除;否则,将删除位置后的元素前移一位。

5.实现查找操作。

遍历串中的每个元素,检查是否与要查找的字符或子串相等,若相等则返回其位置。

6.实现输出操作。

遍历串中的每个元素,将其打印出来。

7.构造测试实例,并进行验证。

实验结果:以插入、删除、查找等操作为例,构造测试实例进行验证:假设有一个空串,插入字符'A'到位置0:结果为"A";在串的末尾插入字符'B':结果为"AB";在位置1插入字符'C':结果为"ACB";删除位置3的字符:结果为"AC";查找字符'C'的位置:结果为1实验总结:本次实验主要是对顺序串的基本操作进行了实现和验证。

数据结构实验报告串

数据结构实验报告串

一、实验目的1. 理解串的概念和性质;2. 掌握串的基本操作,如连接、赋值、求长度、定位等;3. 熟悉串的两种存储结构:顺序存储和链式存储;4. 能够实现串的简单应用,如字符串匹配、子串查找等。

二、实验环境1. 操作系统:Windows 102. 编程语言:C++3. 开发环境:Visual Studio 2019三、实验内容1. 串的定义和性质2. 串的顺序存储结构3. 串的链式存储结构4. 串的基本操作5. 字符串匹配算法6. 子串查找算法四、实验步骤1. 定义串的数据结构```cpp#define MAX_SIZE 100typedef struct {char data[MAX_SIZE];int length;} StrString;```2. 实现串的基本操作```cpp// 初始化串void InitString(StrString &S) {S.length = 0;}// 赋值操作void AssignString(StrString &S, StrString T) { for (int i = 0; i < T.length; i++) {S.data[i] = T.data[i];}S.length = T.length;}// 求长度操作int Length(StrString S) {return S.length;}// 定位操作int Index(StrString S, StrString T, int pos) { int i, j;i = pos;for (j = 0; j < T.length && i < S.length; j++, i++) { if (S.data[i] != T.data[j]) {i = i - j;j = 0;}}if (j == T.length) {return i - T.length + 1;}return 0;}```3. 实现字符串匹配算法```cpp// 字符串匹配算法(KMP算法)int KMPMatch(StrString S, StrString T) {int i, j;int next[T.length];// 构建next数组for (i = 1, j = 0; i < T.length; i++) {while (j > 0 && T.data[i] != T.data[j]) {j = next[j - 1];}if (T.data[i] == T.data[j]) {j++;}next[i] = j;}// 匹配过程i = 0;j = 0;while (i < S.length && j < T.length) { if (S.data[i] == T.data[j]) {i++;j++;} else if (j > 0) {j = next[j - 1];} else {i++;}}if (j == T.length) {return i - j;}return 0;}```4. 实现子串查找算法```cpp// 子串查找算法(朴素算法)int SubStringMatch(StrString S, StrString T) {int i, j;for (i = 0; i <= S.length - T.length; i++) {j = 0;while (j < T.length && S.data[i + j] == T.data[j]) {j++;}if (j == T.length) {return i;}}return 0;}```五、实验结果与分析1. 初始化串、赋值操作、求长度操作、定位操作均能正常执行,符合预期。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验报告实验三串实验目的:1. 熟悉串类型的实现方法,了解简单文字处理的设计方法;2. 熟悉C语言的字符和把字符串处理的原理和方法;3. 熟悉并掌握模式匹配算法。

实验原理:顺序存储结构下的关于字符串操作的基本算法。

模式匹配算法BF、KMP实验内容:4-19. 在4.4.3节例4-6的基础上,编写比较Brute-Force算法和KMP算法比较次数的程序。

4-20. 设串采用静态数组存储结构,编写函数实现串的替换Replace(S,start,T,V),即要求在主串S中,从位置start开始查找是否存在字串T。

若主串S中存在子串T,则用子串V替换子串T,且函数返回1;若主串S中不存在子串T,则函数返回0;并要求设计主函数进行测试。

一个测试例子为:S=“I am a student”,T=“student”,V=“teacher”。

程序代码:4-19的代码:/*静态存储结构*/typedef struct{char str[MaxSize];int length;}String;/*初始化操作*/void Initiate(String *S){S->length=0;}/*插入子串操作*/int Insert(String *S, int pos, String T)/*在串S的pos位置插入子串T*/{int i;if(pos<0||pos>S->length){printf("The parameter pos is error!\n");return 0;}else if(S->length+T.length>MaxSize){printf("The space of the array is not enough!\n");return 0;}else{for(i=S->length-1; i>=pos; i--)S->str[i+T.length]=S->str[i];/*依次后移数据元素*/for(i=0; i<T.length; i++)S->str[pos+i]=T.str[i]; /*插入*/S->length=S->length+T.length;/*产生新的串长度值*/return 1;}}/*删除子串操作*/int Delete(String *S, int pos, int len)/*删除串S的从pos位置开始长度为len的子串值*/{int i;if(S->length<=0){printf("No elements deleting!\n");return 0;}else if(pos<0||len<0||pos+len>S->length){printf("The parameters pos and len are not correct!\n"); return 0;}else{for(i=pos+len; i<=S->length-1; i++)S->str[i-len]=S->str[i];/*依次前移数据元素*/S->length=S->length-len;/*产生新的串长度值*/return 1;}}/*取子串操作*/int SubString(String S, int pos, int len, String *T)/*取串S的从pos位置开始长度为len的子串值赋给子串T*/{int i;if(pos<0||len<0||pos+len>S.length){printf("The parameters pos and len are not correct!\n");return 0;}else{for(i=0; i<=len; i++)T->str[i]=S.str[pos+i]; /*给子串T赋值*/T->length=len; /*给子串T的长度域赋值*/return 1;}}/*查找子串BF(Brute-Force)操作*/int BFIndex(String S, int start, String T)/*查找主串S从start开始的子串T,找到返回T在S中的开始字符下标,否则返回-1*/ {int i= start, j=0, v;while(i<S.length && j<T.length){if(S.str[i]==T.str[j]){i++;j++;}else{i=i-j+1;j=0;}}if(j==T.length)v=i-T.length;elsev=-1;return v;}/*查找子串KMP(D.E.Knuth-J.H.Morris-V.R.Pratt)操作*/int KMPIndex(String S, int start, String T, int next[]) /*查找主串S从start开始的子串T,找到返回T在S中的首字符下标,*/ /*否则返回-1*//*数组Next中存放有模式串T的next[j]值*/{int i= start, j=0, v;while(i<S.length && j<T.length){if(S.str[i]==T.str[j]){i++;j++;}else if(j==0) i++;else j=next[j];}if(j==T.length)v=i-T.length;elsev=-1;return v;}/*求模式串next[j]值的操作*/void GetNext(String T, int next[])/*求子串T的next[j]值并存放于数组next中*/{int j=1, k=0;next[0]=-1;next[1]=0;while(j<T.length){if(T.str[j]=T.str[k]){next[j+1]=k+1;j++;k++;}else if(k==0){next[j+1]=0;j++;}else k=next[k];}}/*查找子串BF(Brute-Force)算法累计次数*/int BFIndexC(String S, int start, String T)/*查找主串S从start开始的子串T,找到返回T在S中的开始字符下标,否则返回-1*/ {int i= start, j=0, t=0;while(i<S.length && j<T.length){if(S.str[i]==T.str[j]){i++;j++;}else{i=i-j+1;j=0;}t++;}return t;}/*查找子串KMP(D.E.Knuth-J.H.Morris-V.R.Pratt)操作*/int KMPIndexC(String S, int start, String T, int next[])/*查找主串S从start开始的子串T,找到返回T在S中的首字符下标,*//*否则返回-1*//*数组Next中存放有模式串T的next[j]值*/{int i= start, j=0, t=0;while(i<S.length && j<T.length){if(S.str[i]==T.str[j]){i++;j++;}else if(j==0)i++;else j=next[j];t++;}return t;}测试主函数:#include<stdio.h>#define MaxSize 100#include"SString.h"#include"BFandKMP.h"void main(void){String S={{"cddcdc"},6}, T={{"abcde"},5};String S1={{"aaaaaaaa"},8}, T1={{"aaaab"},5};String S2={{"aaaaaaaaaaaaaaaaad"},18}, T2={{"aaaab"},5}; int next[20], count;count=BFIndexC(S,0,T);printf("从S中查找T的Brute-Force算法比较次数:%d\n",count); GetNext(T, next);count=KMPIndexC(S,0,T,next);printf("从S中查找T的KMP算法比较次数:%d\n",count);count=BFIndexC(S1,0,T1);printf("从S1中查找T1的Brute-Force算法比较次数:%d\n",count); GetNext(T1, next);count=KMPIndexC(S1,0,T1,next);printf("从S1中查找T1的KMP算法比较次数:%d\n",count);count=BFIndexC(S2,0,T2);printf("从S2中查找T2的Brute-Force算法比较次数:%d\n",count); GetNext(T2, next);count=KMPIndexC(S2,0,T2,next);printf("从S2中查找T2的KMP算法比较次数:%d\n",count);}4-20的部分代码:Replace函数:/* 从主串S中查找字串T,若存在,并用串V替换串T并返回1,否则,返回0*/ int Replace(String S,int start,String T,String V){int i,v;Initiate(&S);Initiate(&T);Initiate(&V);for(i=0; i<strlen(S.str); i++)S.length=S.length+1;for(i=0; i<strlen(T.str); i++)T.length=T.length+1;for(i=0; i<strlen(V.str); i++)V.length=V.length+1;i=BFIndex(S, 0, T);if (i!=-1){if(Delete(&S, i, T.length))Insert(&S, i, V);for(i=0; i<S.length; i++)printf("%c", S.str[i]);printf("\n");return v=1;}else{printf("主串S中不存在串T\n");return v=0;}}测试主函数:#define MaxSize 80#include<stdio.h>#include<string.h>#include "SString.h"int main(void){ int v;String S={"I am a student."}, T={"student"}, V={"teacher"}; v=Replace(S,0,T,V);printf("返回%d\n",v);}实验结果:4-19.程序调式结果:4-20.程序调式结果:总结与思考KMP算法的比较次数比Brute-Force算法的少。

相关文档
最新文档