串的结构类似与线性表,只不过串的数据元素是一个字符,即是由零个或多个字符组成的有限序列。
一、串的顺序存储
串的顺序存储结构也就是顺序存储,即串中的字符被依次的存在一组连续的存储单元中,可以类比线性表的顺序存储,可以写出其数据结构如下:
1 2 3 4 5 6 | typedef struct st { char *ch; //串存放的起始地址,串中第i个字符存储在ch[i-1]中 int length; //串的长度 int strsize; //分配的存储空间的大小,如果不足,在通过realloc()分配增加空间 }string; |
假设现在的字符串是“friend”,其结构可以用如图所示:
现在我们拿到这个数据结构第一步是要初始化一个串,即首先在内存中开辟一段连续的存储空间(大小可以假先预定MAXSIZE个存储空间),初始化其长度length为0,同时制定其串的最大容量是MAXSZIE,如下:
1 2 3 4 5 6 7 8 9 | //串的初始化操作 string CreateNullString() { string s; s.length=0; s.ch=( char *) malloc (MAXSIZE * sizeof ( char )); s.strsize=MAXSIZE; return s; } |
初始化完成之后,我们可以类比顺序表,对串完成一系列操作,如串拷贝、取子串、串赋值等,
程序示例如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 | #include<stdio.h> #include<stdlib.h> #define MAXSIZE 100 typedef struct st { char *ch; //串存放的起始地址,串中第i个字符存储在ch[i-1]中 int length; //串的长度 int strsize; //分配的存储空间的大小,如果不足,在通过realloc()分配增加空间 }string; //串的初始化操作 string CreateNullString() { string s; s.length=0; s.ch=( char *) malloc (MAXSIZE * sizeof ( char )); s.strsize=MAXSIZE; return s; } //判断空串 int isEmpty(string s) { if (s.length==0) return 1; else return 0; } //赋值操作 void StringAssign(string *s1, char s2[]) { int i=0; while (s2[i]!= '\0' ) // '\0' 是字符串的结束符,任何字符串之后都会自动加上'\0' i++; //计算s2的长度 if (i>s1->strsize) { //所赋值的字符数组超过字符串的默认容量,则增加存储空间 s1->ch=( char *) malloc (i* sizeof ( char )); s1->strsize=i; } s1->length=i; for (i=0;i<s1->length;i++) s1->ch[i]=s2[i]; //从第一个字符开始逐个字符赋值 } //串拷贝操作 void StringCopy(string *s1,string s2) { if (s1->strsize<s2.length) { s1->ch=( char *) realloc (s1->ch,s2.length* sizeof ( char )); s1->strsize=s2.length; } s1->length=s2.length; int i; for (i=0;i<s1->length;i++) s1->ch[i]=s2.ch[i]; } //求串的长度 int StringLength(string s) { return s.length; } //串的连接操作 void concat(string *s,string s1,string s2) { if (s->strsize<s1.length+s2.length) { s->ch=( char *) realloc (s->ch,(s1.length+s2.length)* sizeof ( char )); s->strsize=s1.length+s2.length; } s->length=s1.length+s2.length; //两串连接 int i; for (i=0;i<s1.length;i++) //将s1复制到s中 s->ch[i]=s1.ch[i]; for (;i<s->length;i++) s->ch[i]=s2.ch[i-s1.length]; //将s2复制到s中去 } //取子串操作 int substr(string s, int i, int len,string *t) { /* i表示从字符串s的第i个位置开始截取(索引从1开始) len表示截取字符串的长度 */ if (i<=0 || i>s.length || len<0 || len>s.length-i+1) //参数不合法 return 0; if (t->length<len) //存储空间不够,继续分配存储空间 { t->ch=( char *) realloc (t->ch,len* sizeof ( char )); t->strsize=len; } t->length=len; int k; for (k=0;k<t->length;k++) t->ch[k]=s.ch[i-1+k]; return 1; } //插入操作 int insertString(string *s, int i,string t) { //在字符串s的第i个位置插入字符串t if (i<=0 || i>s->length+1) return 0; if (s->strsize<s->length+t.length) //空间不足 { s->ch=( char *) realloc (s->ch,(s->length+t.length)* sizeof ( char )); s->strsize=s->length+t.length; } int k; for (k=s->length-1;k>=i-1;k--) //将s中的后i个字符后移到后面 s->ch[k+t.length]=s->ch[k]; s->length=s->length+t.length; for (k=0;k<t.length;k++) //将t的值赋值给s s->ch[k+i-1]=t.ch[k]; return 1; } //删除操作 int deleteString(string *s, int i, int len) { //从s的第i个字符开始删除len个字符 if (i<=0 || i>s->length || len<0 || len>s->length-i+1) //参数不合法 return 0; int k; for (k=i+len-1;k<s->length;k++) //从s的i+len-1个位置开始将其后的所有字符前移 s->ch[k-len]=s->ch[k]; s->length-=len; return 1; } //输出操作 void print(string s) { int i; for (i=0;i<s.length;i++) printf ( "%c" ,s.ch[i]); printf ( "\n" ); } void main() { string s1=CreateNullString(); string s2=CreateNullString(); string s3=CreateNullString(); char ch[MAXSIZE]; printf ( "请输入主串:\n" ); gets (ch); StringAssign(&s1,ch); printf ( "主串 s1 为:" ); print(s1); StringCopy(&s2,s1); printf ( "拷贝串操作结果如下,结果如下 s2 :" ); print(s2); printf ( "删除操作(1——s1.length-3 全删):" ); deleteString(&s2,1,s1.length-3); print(s2); printf ( "插入操作,插入到s2的第2个位置上,请输入插入的字符串:" ); gets (ch); StringAssign(&s3,ch); insertString(&s2,2,s3); print(s2); printf ( "取子串操作(取s1的子串【2-4】):" ); substr(s1,2,3,&s3); print(s3); printf ( "串连接操作【将s1与s3合并】:" ); concat(&s1,s1,s2); print(s1); } |
结果如下:
二、串的链式存储
串的链式存储结构称为串的链式存储,即串中的每一个节点包括两个部分:数据域和指针域,其中数据域用来存放字符,指针域用来存放指向下一个节点的指针。
由此可得串的链式数据结构如下:
1 2 3 4 5 | typedef struct node { char ch; //字符域 struct node *next; //指针域,存放下一个结点的地址 }node,*linkstr; |
如下所示:
其初始化操作主要是开辟头结点,同时让它的下一个指针指向为NULL:
1 2 3 4 5 6 7 8 9 | //初始化操作 linkstr CreateNullString() { linkstr s; s=(linkstr) malloc ( sizeof (node)); if (s!=NULL) s->next=NULL; return s; } |
http://www.cnblogs.com/helloworldcode/p/6978746.html