串(四)
2016-06-24 22:58
369 查看
4_1串的定义
串,是由零个或多个字符组成的有限序列当且仅当俩个串的长度相等并且各个对应位置上的字符都相同时,这俩个串才是相等的
空串是任何串的子串
4_2_1 串的顺序存储结构
在顺序串中,串中的字符被依次存放在一组连续的存储单元里一般来会所,一个字节(8位)可以表示一个字符(即该字符的ASCII码).因此,一个内存单元可以存储多个字符。
(例如:一个32位的内存单元可以存储4个字符)
从上一点可以得出,串的顺序存储有俩种方法:一种是每个单元只存一个字符,称为非紧缩格式(存储密度小);另一种是每个单元存放多个字符,称为紧缩格式(存储密度大).
对于非紧缩格式的顺序串,定义如下:
typedef struct { char data[MaxSize]; int length; }SqString;
顺序串上实现串基本运算的算法
将一个字符串常量赋给串s,即生成一个值等于cstr的串s:StrAssign(SqString &s,char cstr[])void StrAssign(SqString &s,char cstr[]) { int i; for(i=0;cstr[i]!='\0';i++) s.data[i] = cstr[i]; s.length = i; }
将串t复制给串s:StrCopy(s,t)
void StrCoopy(SqString &s,SqString t) { int i; //for(i=0;t.data[i]!='\0';i++) for(i=0;i>t.length;i++) s.data[i] = t.data[i]; s.length = t.length; }
判断串相等:若俩个串s与t相等返回真(1);否则返回假(0):StrEqual(s,t)
bool StrEqual(s,t) { bool same = true; int i; if(s.length != t.length) same = false; else for(i=0;i<s.length;i++) if(s.data[i]!=t.data[i]) { same = false; break; } return same; }
求串长:返回串s中字符个数:StrLength(s)
int StrLength(s) { return s.length; }
串连接:返回由俩个串s和t连接在一起形成的新串:Concat(s,t)
SqString Concat(SqString s,SqString t) { SqString str; int i; str.length = s.length + t.length; for(i=0;i<s.length;i++) str[i] = s.data[i]; for(i=0;i<t.length;i++) str[s.length+i] = t.data[i]; return str; }
求子串:返回串s中第i(1≤i≤StrLength(s)1\le i \le StrLength(s))个字符开始的,由连续j个字符组成的子串。参数不正确时返回一个空串:SubStr(s,i,j)
SqString SubStr(SqString s,int i,int j) { SqString str; int k; str.length = 0; if(j<0 || i+j-1>s.length) return str; //i和j的值并不能被改变,只能使用临时变量k for(k=i-1;k<i-1+j;k++) str[k] = s.data[k]; str.length = j; return str; }
将串s2插入到串s1的第i(1≤i≤StrLength(s)1\le i \le StrLength(s))个字符中,即将s2的第一个字符作为s1的第i个字符,并返回产生的新串。参数不正确时返回一个空串:InsStr(s1,i,s2)
SqString InsStr(SqString s1,int i,SqString s2) { SqString str; int j; str.length = 0; if(i<=0 || i>s1.length+1) return str; for(j=0;j<i-1;j++) str[j] = s1.data[j]; for(j=0;j<s2.length;j++) str[i-1+j] = s2.data[j]; for(j=i-1;j<s1.length;j++) str[i-1+s2.length] = s1.data[j]; str.length = s1.length + s2.length; return str; }
从串s删去第i(1≤i≤StrLength(s)1\le i \le StrLength(s))个字符开始的长度为j的子串,并返回产生的新串。参数不正确时返回一个空串:DelStr(s,i,j)
SqString DelStr(SqString s,int i,int j) { SqString str; int k; str.length = 0; if(略) return str; for(k=0;k<i-1;k++) str[k] = s.data[k]; for(k=i-1+j;k<j.length;j++) str[k-j] = s.data[k]; str.length = s.length - j; return str; }
在串s中,将第i(1≤i≤StrLength(s)1\le i \le StrLength(s))个字符开始的长度为j的子串用串t替换,并返回产生的新串。参数不正确时返回一个空串:RepStr(s,i,j,t)
SqString RepStr(SqString s,int i,intj,SqString t) { SqString str; str.length = 0; int k; if(略) return str; for(k=0;k<i-1;j++) str[j] = s.data[j]; for(k=0;k<t.length;j++) str[i+k-1] = t.data[k]; for(k=i-1+j;j<s.length;j++) str[i-1+t.length] = s.data[k]; str.length = s.length-j+t.length return str; }
输出串s的所有元素值:DispStr(s)
void DispStr(SqString s) { int i; if(s.length>0) { for(i=0;i<s.length;i++) printf("%c",s.data[i]); printf("\n"); } }
例题 4_1 设计顺序串上实现串比较运算StrCmp(s,t)的算法
int Strcmp(SqString s,SqString t) { 略 }
例题 4_2 以顺序串作为串的存储结构,设计一个算法求串s中出现的第一个最长的连续相同字符构成的平台
思路用index保存最长的平台在s中的开始位置,max保存其长度,先将它们初始化为0.扫描串s,计算局部重复子串的长度length,若max较大,则更新max,并用index记下其开始位置。
void LongestString(SqString s,int &index,int &max) { int i=0,length=1,max=0,start=0; while(i<s.length-1) { if(s.data[i] == s.data[i+1]) i++; length++; else if(max<length) { max = length; index = start; } i++; start = i; length = 1; } }
4_2_2 串的链式存储结构-链串
链串的组织形式与一般的链表相似,主要的区别在于链串中的一个节点可以存储多个字符。通常将链串中每个节点所存储的字符个数称为节点大小
链串节点大小的选择与顺序串的格式类似。节点越大,则存储密度越大。但存储密度越大,一些操作越是不便,且可能引起大量字符移动。
这里规定链串节点大小均为1
typedef struct snode { char data; struct snode *next; }LiSting;
链串上实现串基本运算的算法
将一个字符串常量cstr赋给串s,即生成一个其值等于cstr的串s。采用尾插法简历串s:StrAssign(s,cstr);StrAssign(LiString * &s,char cstr[]) { int i; LiString *r,*p; s = (LiString *)malloc(sizeof(LiString)); r = s; for(i=0;cstr[i] != '\0';i++) { p = (LiString *)malloc(sizeof(LiString)); p->data = cstr[i]; r->next = p; r = p; } r->next = NULL; }
将串t赋值给串s。采用尾插法建立复制后的链串s:StrCopy(s,t);
void StrCopy(LiString * &s,LiString * t) { LiString *p = t->next,*r,*q; s = (LiString *)malloc(sizeof(LiString)); r = s; while(p!=null) { q = (LiString *)malloc(sizeof(LiString)); q->data = p->data; r->next = q; r = q; p = p->next; } r->next = NULL; }
判断串相等,若俩个串s与t相等则返回真,否则返回假:StrEqual(s,t)
bool StrEqual(LiString *s,LiString *t) { LiString *p = s,*q = t; while(p!=NULL && q!=NULL && p->data = q->data) { p = p->next; q = q->next; } if(p==NULL && q==NULL) { return true; } else return false; }
求串长:返回串s中字符个数;StrLength(s)
int StrLength(LiString *s) { int i=0; LiString *r; r = s->next; while(r!=null) { i++; r= r->next; } return i; }
串连接:返回由俩个串s和t连接在一起形成的新串。采用尾插法建立链串str并返回其地址;Concat(s,t)
LiString Concat(LiString *s,LiString *t) { LiString *str,*r,*p,*q; str = (LiString *)malloc(sizeof(LiString)); r = str; p = s->next; while(p!=null) { q = (LiString *)malloc(sizeof(LiString)) q->data = p->data; r-next = q; r = q; p = p->next; } p = t->next; while(p!=NULL) { q = (LiString *)malloc(sizeof(LiString)) q->data = p->data; r-next = q; r = q; p = p->next; } r->next = NULL; return str; }
求子串:返回串s中从第i个字符开始的,由连续j个字符组成的子串,参数不正确时返回一个空串。以下采用尾插法简历链串str并返回其地址;SubStr(s,i,j)
//正确的做法应该是利用链表,取到i-1的节点,这其实是一个公式 LiString * SubStr(LiString * s,int i,int j) { int k = 0; LiString *str,*p,*q,*r; p = s->next; str = (LiString *)malloc(sizeof(LiString)); r = str; if(i<=0 || i>StrLength(s) || j<0 || i+j-1>StrLength(s)) { return str; } for(k=0;k<i-1;k++) p = p->next; //经过上面,已经把p指向第i个节点 for(k=0;k<j;k++) { q = (LiString *)malloc(sizeof(LiString)); q->data = p->data; r->next = q; r = q; p = p->next; } r->next = NULL; return str;
将串s2插入到串s1的第i个字符位置,即将s2的第1个字符作为s1的第i个字符,s2的第2个字符作为s1的第i+1个字符,等等,并返回产生的新串,参数不正确时返回一个空串。以下采用尾插法:InsStr(s1,i,s2)
//先插进去s1的前i个,然后插s2,再插s1剩下的,so easy LiString * InsStr(LiString *s,int i,LiString *t) { int k; LiString *str,*p,*r,*q,*m; str = (LiString *)malloc(sizeof(LiString)); r = str; p = s->next; m = t->next; if(i<=0 || i>StrLength(s)+1) { return str; } for(k=0;k<i-1;k++) { q = (LiString *)malloc(sizeof(LiString)); q->data = p->data; r->next = q; r = q; p = p->next; } while(m!=NULL) { q = (LiString *)malloc(sizeof(LiString)); q->data = m->data; r->next = q; r = q; m = m->next; } while(p!=null) { q = (LiString *)malloc(sizeof(LiString)); q->data = p->data; r->next = q; r = q; p = p->next; } r->next = NULL; return str; }
从串s中删去从第i个字符开始的长度为j的子串,并返回产生的新串,参数不正确时返回一个空串。以下采用尾插法建立链串str并返回其地址;
LiStrng * DelStr(LiString *s,int i,int j) { int k; LiString * str,*r,*p,*q; str = (LiString *)malloc(sizeof(LiString)); r = str; p = s->next; if(略) return str; for(k=0;k<i-1;k++) { q = (LiString *)malloc(sizeof(LiString)); q->data = p->data; r->next = q; r = q; p = p->next; } for(k=0;k<j;k++) p = p->next; while(p!=null) { q = (LiString *)malloc(sizeof(LiString)); q->data = p->data; r->next = q; r = q; p = p->next; } r->next = NULL; return str; }
在串s中,将第i个字符开始的j个字符构成的子串用串t替换,并返回产生的新串,参数不正确时返回一个空串。以下采用尾插法建立链串str并返回其地址;RepStr(s,i,j,t)
LiString * RepStr(LiString *s,int i,int j,LiString *t) { int k; LiString *str,*p,*q,*r,*p1; str = (LiString *)malloc(sizeof(LiString)); r = str; p = s->next; p1 = t->next; if(略) return str; for(k=0;k<i-1;k++) { q = (LiString *)malloc(sizeof(LiString)); q->data = p->data; r->next = q; r = q; p = p->next; } for(k=0;k<j;k++) p = p->next; while(p1!=null) { q = (LiString *)malloc(sizeof(LiString)); q->data = p1->data; r->next = q; r = q; p1 = p1->next; } while(p!=null) { q = (LiString *)malloc(sizeof(LiString)); q->data = p->data; r->next = q; r = q; p = p->next; } r->next = NULL; return str; }
输出串s的所有元素值;DispStr(s)
void DispStr(LiString * s) { LiString *p = s->next; while(p!=NULL) { printf("%c",p->data); p = p->next; } printf("\n"); }
例题 4_3 以链串为存储结构,设计一个算法把最先出现的子串ab改为xyz。
void Repl(LiString * &s) { LiString *p,*q; p = s->next; int find = 0; while(p->next!=NULL && find==0) { if(p->data=='a' && p->next-data == 'b') { p->data = 'x'; p->next-data == 'z' q = (LiString *)malloc(sizeof(LiString)); q->data = 'y'; q->next = p->next; p->next = q; find = 1; } else p = p->next; } }
-
相关文章推荐
- 锁屏背景替换-xp篇
- 灵感
- JAVA之IO 基础(字节流和字符流)
- Qt .pro文件部分变量解析
- java_简单的写个二叉树
- vim的配置
- 剑指offer 面试题2 Singleton模式 C++实现
- Android Tips
- ubuntu 14.04 以root权限启动chrome
- yield return 学习
- 一些简单知识点
- Android开发--CardView使用
- filter过滤器设置URL例外
- 写简历注意事项
- PAT乙级练习题B1016.部分A+B
- 水管工游戏
- 鸽笼原理应用举例
- Android studio 目录结构
- XXX P2P公司堡垒机项目帐号集中管理定制开发说明
- 笔记:centos6 rsync配置测试