数据结构串实验报告
【精品】数据结构串实验报告
【精品】数据结构串实验报告
(仅校内可用)
本次实验是基于数据结构串的相关知识,设计、实现及实验关于串的操作,并要求我们编写综合性实验报告。
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. 初始化串、赋值操作、求长度操作、定位操作均能正常执行,符合预期。
数据结构串的实验总结
数据结构串的实验总结《数据结构串的实验总结》整体感受嘛,这数据结构中的串实验就像一场充满挑战与惊喜的旅程。
开始的时候,真觉得有些头疼,就像面对一个错综复杂的迷宫,完全不知道从哪儿入手。
具体收获可真是不少。
首先,我对串的基本概念有了透彻的理解,什么是串,串的长度、空串、空格串等等。
在实现串的操作时,比如串的连接、匹配之类的,那可真是让我费了不少心思。
比如说在实现串的模式匹配算法中的BF算法时,我才清楚需要挨个比较字符,就像在人群中逐个查找一个特定的人一样辛苦但又很有成就感。
还有KMP算法,这个算法刚开始理解简直难上天了,它那复杂的部分匹配值计算和next数组的构建,但是一旦理解了它的精髓,就感觉像发现了一个快捷通道。
原来KMP 算法就是利用已经比较过的信息,避免不必要的比较,就像你走过一遍迷宫,记住了哪些路是死胡同,下次走的时候就可以避开了。
重要发现也得记一笔。
在做串的存储结构实验的时候,我发现顺序存储结构在某些情况下很方便,比如串的长度固定或者不需要频繁插入删除的时候。
而链式存储结构则在灵活处理串的变化方面更有优势,这就像是住在公寓和房车的区别,一个固定但是稳定,一个虽然变动大但是更灵活,可以随时根据需求调整内部布局。
反思一下,自己在做实验的过程中太过于关注实现结果而忽略了算法的时间复杂度和空间复杂度优化。
比如在BF算法中,如果字符串很长,那简单的逐个比较效率是非常低的,当时怎么就没有多想想怎么优化呢,真是太不应该了。
现在想想,如果当时能从一开始就着重关注效率方面的问题,后面可能就不需要花这么多时间返工了。
从这个串的实验中得到的启示就是做事情之前一定要考虑全面。
遇到难题的时候不要害怕,像理解KMP算法一样,多花时间多思考,总能找到解决方案的。
而且在解决问题的过程中,要不断思考有没有更好更高效的方法,不能仅仅满足于把功能实现了就好。
要从各个方面去考量,就像看待一个人的综合素质一样,不仅要看他能不能完成任务,还要看他完成任务的质量和效率。
串-数据结构实验报告
串-数据结构实验报告串数据结构实验报告一、实验目的本次实验的主要目的是深入理解和掌握串这种数据结构的基本概念、存储方式以及相关的操作算法。
通过实际编程实现串的基本操作,提高对数据结构的理解和编程能力,培养解决实际问题的思维和方法。
二、实验环境本次实验使用的编程语言为C++,开发工具为Visual Studio 2019。
三、实验原理(一)串的定义串是由零个或多个字符组成的有限序列。
在本次实验中,我们主要关注的是字符串。
(二)串的存储方式1、顺序存储定长顺序存储:使用固定长度的数组来存储字符串,长度不足时用特定字符填充。
堆分配存储:根据字符串的实际长度动态分配存储空间。
2、链式存储每个节点存储一个字符,并通过指针链接起来。
(三)串的基本操作1、串的创建和初始化2、串的赋值3、串的连接4、串的比较5、求子串6、串的插入和删除四、实验内容及步骤(一)顺序存储方式下串的实现1、定义一个结构体来表示顺序存储的字符串,包含字符数组和字符串的实际长度。
```cppstruct SeqString {char str;int length;};```2、实现串的创建和初始化函数```cppSeqString createSeqString(const char initStr) {int len = strlen(initStr);SeqString s;sstr = new charlen + 1;strcpy(sstr, initStr);slength = len;return s;}```3、串的赋值函数```cppvoid assignSeqString(SeqString& s, const char newStr) {delete sstr;int len = strlen(newStr);sstr = new charlen + 1;strcpy(sstr, newStr);slength = len;}```4、串的连接函数```cppSeqString concatSeqString(const SeqString& s1, const SeqString& s2) {SeqString result;resultlength = s1length + s2length;resultstr = new charresultlength + 1;strcpy(resultstr, s1str);strcat(resultstr, s2str);return result;}```5、串的比较函数```cppint compareSeqString(const SeqString& s1, const SeqString& s2) {return strcmp(s1str, s2str);}```6、求子串函数```cppSeqString subSeqString(const SeqString& s, int start, int len) {SeqString sub;sublength = len;substr = new charlen + 1;strncpy(substr, sstr + start, len);substrlen ='\0';return sub;}```7、串的插入函数```cppvoid insertSeqString(SeqString& s, int pos, const SeqString& insertStr) {int newLength = slength + insertStrlength;char newStr = new charnewLength + 1;strncpy(newStr, sstr, pos);strcpy(newStr + pos, insertStrstr);strcpy(newStr + pos + insertStrlength, sstr + pos);delete sstr;sstr = newStr;slength = newLength;}```8、串的删除函数```cppvoid deleteSeqString(SeqString& s, int start, int len) {int newLength = slength len;char newStr = new charnewLength + 1;strncpy(newStr, sstr, start);strcpy(newStr + start, sstr + start + len);delete sstr;sstr = newStr;slength = newLength;}```(二)链式存储方式下串的实现1、定义一个节点结构体```cppstruct LinkNode {char data;LinkNode next;LinkNode(char c) : data(c), next(NULL) {}};```2、定义一个链式存储的字符串类```cppclass LinkString {private:LinkNode head;int length;public:LinkString(const char initStr);~LinkString();void assign(const char newStr);LinkString concat(const LinkString& other);int compare(const LinkString& other);LinkString subString(int start, int len);void insert(int pos, const LinkString& insertStr);void deleteSub(int start, int len);};```3、实现各个函数```cppLinkString::LinkString(const char initStr) {length = strlen(initStr);head = NULL;LinkNode p = NULL;for (int i = 0; i < length; i++){LinkNode newNode = new LinkNode(initStri);if (head == NULL) {head = newNode;p = head;} else {p>next = newNode;p = p>next;}}}LinkString::~LinkString(){LinkNode p = head;while (p) {LinkNode temp = p;p = p>next;delete temp;}}void LinkString::assign(const char newStr) {//先释放原有的链表LinkNode p = head;while (p) {LinkNode temp = p;p = p>next;delete temp;}length = strlen(newStr);head = NULL;p = NULL;for (int i = 0; i < length; i++){LinkNode newNode = new LinkNode(newStri);if (head == NULL) {head = newNode;p = head;} else {p>next = newNode;p = p>next;}}}LinkString LinkString::concat(const LinkString& other) {LinkString result;LinkNode p1 = head;LinkNode p2 = otherhead;LinkNode p = NULL;while (p1) {LinkNode newNode = new LinkNode(p1->data);if (resulthead == NULL) {resulthead = newNode;p = resulthead;} else {p>next = newNode;p = p>next;}p1 = p1->next;}while (p2) {LinkNode newNode = new LinkNode(p2->data);if (resulthead == NULL) {resulthead = newNode;p = resulthead;} else {p>next = newNode;p = p>next;}p2 = p2->next;}resultlength = length + otherlength;return result;}int LinkString::compare(const LinkString& other) {LinkNode p1 = head;LinkNode p2 = otherhead;while (p1 && p2 && p1->data == p2->data) {p1 = p1->next;p2 = p2->next;}if (p1 == NULL && p2 == NULL) {return 0;} else if (p1 == NULL) {return -1;} else if (p2 == NULL) {return 1;} else {return p1->data p2->data;}}LinkString LinkString::subString(int start, int len) {LinkString sub;LinkNode p = head;for (int i = 0; i < start; i++){p = p>next;}for (int i = 0; i < len; i++){LinkNode newNode = new LinkNode(p>data);if (subhead == NULL) {subhead = newNode;} else {LinkNode temp = subhead;while (temp>next) {temp = temp>next;}temp>next = newNode;}p = p>next;}sublength = len;return sub;}void LinkString::insert(int pos, const LinkString& insertStr) {LinkNode p = head;for (int i = 0; i < pos 1; i++){p = p>next;}LinkNode insertHead = insertStrhead;while (insertHead) {LinkNode newNode = new LinkNode(insertHead>data);newNode>next = p>next;p>next = newNode;p = p>next;insertHead = insertHead>next;}length += insertStrlength;}void LinkString::deleteSub(int start, int len) {LinkNode p = head;for (int i = 0; i < start 1; i++){p = p>next;}LinkNode temp = p>next;for (int i = 0; i < len; i++){LinkNode delNode = temp;temp = temp>next;delete delNode;}p>next = temp;length = len;}```(三)测试用例1、顺序存储方式的测试```cppint main(){SeqString s1 = createSeqString("Hello");SeqString s2 = createSeqString("World");SeqString s3 = concatSeqString(s1, s2);std::cout <<"连接后的字符串: "<< s3str << std::endl; int cmpResult = compareSeqString(s1, s2);if (cmpResult < 0) {std::cout <<"s1 小于 s2" << std::endl;} else if (cmpResult == 0) {std::cout <<"s1 等于 s2" << std::endl;} else {std::cout <<"s1 大于 s2" << std::endl;}SeqString sub = subSeqString(s1, 1, 3);std::cout <<"子串: "<< substr << std::endl; insertSeqString(s1, 2, s2);std::cout <<"插入后的字符串: "<< s1str << std::endl; deleteSeqString(s1, 3, 2);std::cout <<"删除后的字符串: "<< s1str << std::endl; return 0;}```2、链式存储方式的测试```cppint main(){LinkString ls1("Hello");LinkString ls2("World");LinkString ls3 = ls1concat(ls2);std::cout <<"连接后的字符串: ";LinkNode p = ls3head;while (p) {std::cout << p>data;p = p>next;}std::cout << std::endl;int cmpResult = ls1compare(ls2);if (cmpResult < 0) {std::cout <<"ls1 小于 ls2" << std::endl;} else if (cmpResult == 0) {std::cout <<"ls1 等于 ls2" << std::endl;} else {std::cout <<"ls1 大于 ls2" << std::endl;}LinkString sub = ls1subString(1, 3);std::cout <<"子串: ";p = subhead;while (p) {std::cout << p>data;p = p>next;}std::cout << std::endl;ls1insert(2, ls2);std::cout <<"插入后的字符串: ";p = ls1head;while (p) {std::cout << p>data;p = p>next;}std::cout << std::endl;ls1deleteSub(3, 2);std::cout <<"删除后的字符串: ";p = ls1head;while (p) {std::cout << p>data;p = p>next;}std::cout << std::endl;return 0;}```五、实验结果及分析(一)顺序存储方式1、连接操作成功实现,输出了正确连接后的字符串。
串的数据结构实验报告
串的数据结构实验报告
《串的数据结构实验报告》
在计算机科学领域,数据结构是非常重要的基础知识之一。
而串(String)作为一种基本的数据结构,在实际应用中也扮演着重要的角色。
本实验报告将介绍串的数据结构以及在实验中的应用和表现。
首先,串是由零个或多个字符组成的有限序列,是一种线性表。
在计算机中,串通常用来表示文本数据,比如字符串、文件名等。
在实际应用中,串的操作非常频繁,比如查找、替换、插入、删除等。
因此,对串的数据结构进行深入的研究和实验是非常有意义的。
在本次实验中,我们选择了C语言作为实验的编程语言,使用指针和动态内存分配来实现串的数据结构。
我们首先定义了一个结构体来表示串,结构体中包括串的长度和字符数组指针。
然后,我们实现了一系列操作函数,比如串的初始化、销毁、拷贝、连接、比较等。
通过这些操作函数,我们可以对串进行各种操作,从而验证串的数据结构的有效性和实用性。
在实验过程中,我们发现串的数据结构在实际应用中表现出了很好的性能和灵活性。
比如,在进行串的连接操作时,我们可以直接使用指针进行操作,而不需要额外的内存开销。
在进行串的比较操作时,我们可以逐个字符进行比较,从而实现高效的比较操作。
这些实验结果表明,串的数据结构在实际应用中具有很高的实用价值。
总的来说,本次实验对串的数据结构进行了深入的研究和实验,验证了串的数据结构在实际应用中的有效性和实用性。
通过本次实验,我们对串的数据结构有了更深入的理解,也为以后的实际应用提供了参考和借鉴。
希望本次实验报
告能对读者有所帮助,也希望能够对串的数据结构进行更深入的研究和探索。
数据结构串实验报告
数据结构串实验报告数据结构串实验报告引言:数据结构是计算机科学中的重要概念之一,它研究如何组织和存储数据,以便能够高效地访问和操作。
串是一种特殊的数据结构,它由一系列字符组成,可以用来表示文本、字符串等信息。
本实验旨在通过实现串的基本操作,深入理解数据结构的原理和应用。
一、实验目的本实验的主要目的是掌握串的基本操作,包括串的初始化、插入、删除、查找等。
通过实际编程实现这些操作,可以加深对数据结构的理解,并提高编程能力。
二、实验环境本实验使用C语言进行编程,需要在计算机上安装相应的开发环境,如GCC编译器等。
三、实验内容1. 串的初始化串的初始化是指将一个空串创建出来,并为其分配内存空间。
在实验中,可以使用字符数组来表示串,并通过赋值操作将空串初始化。
2. 串的插入串的插入是指在指定位置插入一个或多个字符。
在实验中,可以通过遍历数组,将插入位置之后的字符依次后移,然后将待插入的字符放入指定位置。
3. 串的删除串的删除是指删除指定位置的一个或多个字符。
在实验中,可以通过遍历数组,将删除位置之后的字符依次前移,覆盖待删除的字符。
4. 串的查找串的查找是指在串中查找指定字符或子串,并返回其位置。
在实验中,可以通过遍历数组,逐个比较字符或子串,找到匹配的位置。
五、实验步骤1. 初始化串首先,创建一个字符数组,并将其初始化为空串。
2. 插入字符在指定位置插入一个字符,可以通过遍历数组,将插入位置之后的字符依次后移,然后将待插入的字符放入指定位置。
3. 删除字符删除指定位置的一个字符,可以通过遍历数组,将删除位置之后的字符依次前移,覆盖待删除的字符。
4. 查找字符在串中查找指定字符,可以通过遍历数组,逐个比较字符,找到匹配的位置。
六、实验结果经过实验,我们成功实现了串的初始化、插入、删除和查找等基本操作。
通过不断调试和优化,我们的程序能够高效地处理大量的字符操作,具有较好的性能和稳定性。
七、实验总结通过本次实验,我们深入理解了数据结构中串的原理和应用。
串的数据结构实验报告
串的数据结构实验报告串的数据结构实验报告一、引言在计算机科学中,串(String)是一种基本的数据结构,用于存储和操作字符序列。
串的数据结构在实际应用中具有广泛的用途,例如文本处理、搜索引擎、数据库等。
本实验旨在通过实践掌握串的基本操作和应用。
二、实验目的1. 理解串的概念和基本操作;2. 掌握串的存储结构和实现方式;3. 熟悉串的常见应用场景。
三、实验内容1. 串的定义和基本操作在本实验中,我们采用顺序存储结构来表示串。
顺序存储结构通过一个字符数组来存储串的字符序列,并使用一个整型变量来记录串的长度。
基本操作包括:- 初始化串- 求串的长度- 求子串- 串的连接- 串的比较2. 串的模式匹配串的模式匹配是串的一个重要应用场景。
在实验中,我们将实现朴素的模式匹配算法和KMP算法,并比较它们的性能差异。
四、实验步骤1. 串的定义和基本操作首先,我们定义一个结构体来表示串,并实现初始化串、求串的长度、求子串、串的连接和串的比较等基本操作。
2. 串的模式匹配a. 实现朴素的模式匹配算法朴素的模式匹配算法是一种简单但效率较低的算法。
它通过逐个比较主串和模式串的字符来确定是否匹配。
b. 实现KMP算法KMP算法是一种高效的模式匹配算法。
它通过利用已匹配字符的信息,避免不必要的比较,从而提高匹配效率。
3. 性能比较与分析对比朴素的模式匹配算法和KMP算法的性能差异,分析其时间复杂度和空间复杂度,并讨论适用场景。
五、实验结果与讨论1. 串的基本操作经过测试,我们成功实现了初始化串、求串的长度、求子串、串的连接和串的比较等基本操作,并验证了它们的正确性和效率。
2. 串的模式匹配我们对两种模式匹配算法进行了性能测试,并记录了它们的运行时间和内存占用情况。
结果表明,KMP算法相较于朴素算法,在大规模文本匹配任务中具有明显的优势。
六、实验总结通过本实验,我们深入学习了串的数据结构和基本操作,并掌握了串的模式匹配算法。
串-数据结构实验报告[修改版]
第一篇:串-数据结构实验报告【源程序】:#include #include #include void choose(char *s, int i,int m,char *t);//i位置截取m个字符函数void main() //主函数{ char *s,*t; int i,sl,m;s=(char *)malloc(100*sizeof(char));t=(char *)malloc(100*sizeof(char));printf("\n 输入主字符串s=?"); gets(s); printf("\n s=%s\n",s);printf("\n 输入位置i=?"); scanf("%d",&i); printf("\n i=%d\n",i);printf("\n 输入字符个数m=?"); scanf("%d",&m); printf("\n m=%d\n",m);sl=strlen(s);if(i>sl) printf("i位置出错\n");else if(i+m>sl+1) printf("m位置出错\n");else{choose(s,i,m,t);printf("\n 子串为t=%s\n",t);} } //end_main void choose(char *s, int i,int m,char *t) { int n;int j=0; for(n=i;n三.实验结论及分析串的存储结构包含有顺序存储结构和链式存储结构。
在串的顺序存储结构中,表示串的长度通常有两种方法:一种方法是设置一个串的长度参数,其优点在于便于在算法中用长度参数控制循环过程;另一种方法是在串值得末尾添加结束标记,此种方法的优点在于便于系统自动实现。
数据结构 串 实验报告
数据结构串实验报告实验目的· 了解串的定义和性质· 掌握串的基本操作· 理解串的存储结构及其实现方法实验原理串是由零个或多个字符组成的有限序列。
也可以叫字符串。
如果串中每个字符的位置唯一确定,则称该串为定长串。
现实中大部分字符串是不定长的,为了便于存储和使用,通常将字符串存储成一段连续的内存空间,并在字符串末尾添加一个结束标志,用于表示字符串结束的位置。
串的基本操作包括:串赋值、串求长、串比较、串连接、串子串、串插入和串删除等。
串的存储结构有两种实现方法:顺序存储和链式存储。
顺序存储是将一个串存储在一段连续的内存区域中,而链式存储是将一个串存储在若干个节点中,每个节点中都保存着一个或多个字符。
链式存储的优点是灵活性高,插入和删除操作比顺序存储更容易实现。
但顺序存储是更为常用的实现方法,主要原因是顺序存储对于查找操作更加高效。
实验内容在链式存储方式中,使用一个链表节点表示一个字符,节点包含一个数据域和一个指向下一个节点的指针。
在串连接的操作中,需要对一个链表进行遍历,找到链表的末尾,然后将另一个链表拼接在后面,这个过程中需要修改相应节点的指针。
在串子串、串插入和串删除的操作中,需要遍历链表,找到相应的位置进行操作。
在顺序存储方式中,使用一个数组存储一个串,需要在数组的最后一个位置添加一个结束标志,用来表示串的结束。
在串连接的操作中,需要使用循环将一个串复制到另一个串的后面,同时更新结束标志。
在串子串、串插入和串删除的操作中,需要将数组中的元素进行移动,并更新结束标志。
实验结果串的基本操作都能够成功实现,并且能够在顺序存储和链式存储两种方式中进行操作。
实现过程中需要注意细节,例如顺序存储中需要将数组最后一个位置留给结束标志,链式存储中需要注意指针的修改等。
1. 串是由零个或多个字符组成的有限序列,在实际应用中经常用到。
3. 串的存储结构有两种实现方法:顺序存储和链式存储。
数据结构-串实验报告
实验报告课程数据结构实验名称实验三串学号姓名实验日期:2011/10/27实验三串实验目的: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(1)SString.h/*静态存储结构*/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){printf("参数pos出错!");return 0;}else if(S->length + T.length > MaxSize){printf("数组空间不足无法插入!");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 += T.length;/*产生新的元素个数*/return 1;}}int Delete(String *S, int pos, int len){int i;if(S->length <= 0){printf("数组中未存放字符无元素可删! \n");return 0;}else if(pos < 0 || len < 0 || pos+len > S->length){printf("参数pos和len出错");return 0;}else{for(i = pos+len; i <= S->length-1; i++)S->str[i-len] = S->str[i];/*依次前移*/S->length -= len;/*产生新的长度值*/return 1;}}int SubString(String S, int pos, int len, String *T){int i;if(pos < 0 || len < 0 || pos+len > S.length){printf("参数pos和len出错");return 0;}else{for(i = 0; i < len; i++)T->str[i] = S.str[pos+i];/*给子串T赋值*/T->length = len;/*给子串T的长度域赋值*/return 1;}}(2) BFandKMP.h/*查找子串BF(Brute-Force)操作*/int BFIndex(String S,int start,String T){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;}int KMPIndexA(String S,int start,String T,int next[]) {int i=start,j=0,v;while(i<S.length&&j<T.length){if(j==-1||S.str[i]==T.str[j]){i++;j++;}elsej=next[j];}if(j==T.length)v=i-T.length;elsev=-1;return v;}int KMPIndexB(String S,int start,String T,int next[]) {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++;elsej=next[j];}if(j==T.length)v=i-T.length;elsev=-1;return v;}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){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[]){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;}(3)测试主函数:#include<stdio.h>#define MaxSize 100#include"SString.h"#include"BFandKMP.h"void main(void){String S={{"cddcdc"},6}, T={{"abcde"},5};String S1={{"aaaaaa"},6}, T1={{"aaaab"},5};String S2={{"aaaaaaaaaaaad"},13}, T2={{"aaaab"},5}; int next[20], count;count=BFIndexC(S,0,T);printf("form S find T Brute-Force's times: %d\n",count); GetNext(T, next);count=KMPIndexC(S,0,T,next);printf("form S find T KMP's times: %d\n",count);count=BFIndexC(S1,0,T1);printf("form S1 find T1 Brute-Force's times: %d\n",count); GetNext(T1, next);count=KMPIndexC(S1,0,T1,next);printf("form S1 find T1 KMP's times: %d\n",count); count=BFIndexC(S2,0,T2);printf("form S2 find T2 Brute-Force's times: %d\n",count); GetNext(T2, next);count=KMPIndexC(S2,0,T2,next);printf("form S2 find T2 KMP's times: %d\n",count); printf("This program is made by 10273206\n");}运行结果为:4.20(1) 建立头文件SString.htypedef 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){printf("参数pos出错!");return 0;}else if(S->length + T.length > MaxSize){printf("数组空间不足无法插入!");return 0;}elsefor(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 += T.length;/*产生新的元素个数*/return 1;}}int Delete(String *S, int pos, int len){int i;if(S->length <= 0){printf("数组中未存放字符无元素可删! \n");return 0;}else if(pos < 0 || len < 0 || pos+len > S->length){printf("参数pos和len出错");return 0;}else{for(i = pos+len; i <= S->length-1; i++)S->str[i-len] = S->str[i];/*依次前移*/S->length -= len;/*产生新的长度值*/return 1;}}int SubString(String S, int pos, int len, String *T){int i;if(pos < 0 || len < 0 || pos+len > S.length){printf("参数pos和len出错");return 0;}{for(i = 0; i < len; i++)T->str[i] = S.str[pos+i];/*给子串T赋值*/T->length = len;/*给子串T的长度域赋值*/return 1;}}(2) 建立头文件BFandKMP.hint BFIndex(String S,int start,String T){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;}int KMPIndexA(String S,int start,String T,int next[]){int i=start,j=0,v;while(i<S.length&&j<T.length){if(j==-1||S.str[i]==T.str[j]){i++;j++;}elsej=next[j];}if(j==T.length)v=i-T.length;elsev=-1;return v;}int KMPIndexB(String S,int start,String T,int next[]) {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++;elsej=next[j];}if(j==T.length)v=i-T.length;elsev=-1;return v;}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){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[]){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;}(3)主函数#define MaxSize 80#include<stdio.h>#include<string.h>#include "SString.h"#include"BFandKMP.h"int Replace(String S,int start,String T,String V) {int i;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 1;}else{printf("error!\n");return 0;}}int main(void){ int v;String S={"I am a student."}, T={"student"}, V={"teacher"};v=Replace(S,0,T,V);printf("This program is made by 10273206\n");}运行结果为:总结与思考KMP算法的主要特点是:消除了Brute-Force算法的主串指针在相当多个字符比较相等后,只要有一个字符不相等便回退,也就是回溯的缺点。
数据结构串的实验报告
HUBEI UNIVERSITY OF AUTOMOTIVE TECHNOLOGY数据结构程序设计实验报告03实训题目:串的构造与应用(自行编写)专业:软件工程班级: 软件 161 姓名:王洋学号: 201600819 完成日期: 2017年11月5日2017年11月目录一实验前提 (3)一、1. 实验序言 (3)一、2. 实验目的 (3)一、3. 实验背景 (3)一、4. 实验方式 (4)二程序原理 (4)二、1. 设计思路 (4)二、2. 实验原理 (4)三程序设计 (6)三、1. 主要功能 (6)三、2. 程序界面 (6)四功能实现 (7)四、1. 串的初始化 (7)四、2. 串的插入和删除 (8)四、3. 串的修改及提取子串 (9)四、4. 程序调试 (10)四、5. 程序细节 (10)四、6. 要点函数功能源码 (11)五 }程序总结 (12)五、1. 程序收获清单 (12)五、2. 程序不足改进 (12)六实验总结 (12)一实验前提一、1. 实验序言每一次实验都是一种历练和进步,至少在每次进行序言的时候,都会去总结和想办法改进程序。
即使能力有限,我也切身感受到了进步,以及进步后对程序的稍微深度地思考。
而这次对于串的实验,显然让我感受到了,这样的思考非常欠缺,我所需要完成的还有很多,尤其是随着功能的完善,和深入的编程,会发现其中有更多的地方需要我去改进,尤其是功能越多越深入,这种感觉就越明显一、2. 实验目的串的基本操作的编程实现(2学时,验证型),掌握串的建立、遍历、插入、删除等基本操作的编程实现,也可以进一步编程实现查找、合并、剪裁等操作,存储结构可以在顺序结构或链接结构、索引结构中任选,也可以全部实现。
也鼓励学生利用基本操作进行一些应用的程序设计。
一、3. 实验背景在较熟练的掌握关于对象的编程方法后,这次我就改用了C++进行编写,而且难度要比我预期的要低,效果反而更好了。
同时,串基于字符数组实现要容易得多,而且对于一维数组的具体操作,已经相对较为熟练,而且也提供了很多关于字符串的相关函数,所以为了提高编程水平,这次对于串的操作,都不依赖系统函数和字符串函数,相反,深入初始化,插入,删除,遍历等功能的本质,对字符串的底层进行编程实现。
数据结构串的应用及实现报告
实习报告课程名称: 数据结构实验名称: 串及其应用指导教师:学生班级:学生姓名:学生学号:完成日期:一、 需求分析1、本演示程序用C语言编写,实现串的堆分配存储基本操作、串的建立、串的输出、串的联接、求子串、串匹配、串的插入删除、串的替换等实现方法。
2、程序所达到的功能:(1) 建立串s=“abcdefghijklmn”,串s1=“xyz”,串t=“hijk”(2) 复制串t到t1,并输出t1的长度(3) 在串s的第9个字符位置插入串s1而产生串s2,并输出s2(4) 删除s第2个字符开始的5个字符而产生串s3,并输出s3(5) 将串s第2个字符开始的3个字符替换成串s1而产生串s4,并输出s4(6) 提取串s的第8个字符开始的4个字符而产生串s5,并输出s5(7) 将串s1和串t连接起来而产生串s6,并输出s6(8) 比较串s1和s5是否相等,输出结果二、 概要设计1、编写栈的基本操作函数链串类型定义如下所示:typedef struct snode{char data;struct snode *next;}listring;(1)串赋值 Assign(s,t)将一个字符串常量赋给串s,即生成一个其值等于t的串s(2)串复制 StrCopy(s,t)将串t赋给串s(3)计算串长度 StrLength(s)返回串s中字符个数(4)判断串相等StrEqual(s,t)若两个串s与t相等则返回1;否则返回0。
(5)串连接 Concat(s,t)返回由两个串s和t连接在一起形成的新串。
(6)求子串 SubStr(s,i,j)返回串s中从第i(1≤i≤StrLength(s))个字符开始的、由连续j个字符组成的子串。
(7)插入InsStr (s,i,t)将串t插入到串s的第i(1≤i≤StrLength(s)+1)个字符中,即将t的第一个字符作为s的第i个字符,并返回产生的新串(8)串删除 DelStr (s,i,j)从串s中删去从第i(1≤i≤StrLength(s))个字符开始的长度为j的子串,并返回产生的新串。
串的实验报告
实验名称:串的实验实验日期:2021年X月X日实验地点:XX实验室实验目的:1. 理解串的基本概念和性质。
2. 掌握串的运算方法。
3. 熟悉串的存储结构和实现方式。
实验原理:串(String)是一种特殊的线性表,它是由若干个字符组成的有限序列。
串的运算包括连接、求子串、求长度、判断子串等。
实验步骤:1. 初始化一个串s1,并为其赋值“Hello”。
2. 初始化一个串s2,并为其赋值“World”。
3. 将s1和s2连接,得到一个新的串s3。
4. 从s3中提取子串,得到子串s4。
5. 求s3的长度。
6. 判断s4是否为s3的子串。
实验代码:```python# 定义串的类class String:def __init__(self, data):self.data = data# 连接两个串def concatenate(self, other):return String(self.data + other.data) # 提取子串def substring(self, start, end):return String(self.data[start:end]) # 求长度def length(self):return len(self.data)# 判断子串def is_substring(self, other):return other.data in self.data# 初始化两个串s1 = String("Hello")s2 = String("World")# 连接两个串s3 = s1.concatenate(s2)# 提取子串s4 = s3.substring(0, 5)# 求长度length = s3.length()# 判断子串is_sub = s4.is_substring(s3)# 输出结果print("s1:", s1.data)print("s2:", s2.data)print("s3:", s3.data)print("s4:", s4.data)print("s3的长度:", length)print("s4是否为s3的子串:", is_sub)```实验结果:1. s1: Hello2. s2: World3. s3: HelloWorld4. s4: Hell5. s3的长度: 106. s4是否为s3的子串: True实验分析:1. 通过实验,我们成功实现了串的连接、提取子串、求长度和判断子串等基本运算。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 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算法的少。