首页 > 代码库 > 字符串中的子串替换
字符串中的子串替换
在很多编程语言中,都封装了字符串替换的操作,那么我们这里自己用C语言来实现一个字符串替换的函数。具体需求为:Replace(String S,String T,String V),用V替换主串S中出现的所有与T相等的不重叠的子串。
字符串替换这个操作,需要结合我们前面讲到的几个函数。香格里拉娱乐城
- 首先是Index,找到子串位置。
- 然后是StrDelete,将找到的子串删除。
- 再执行StrInsert,把新的子串插入。
- OK,完成
如果对这三个函数不熟悉,可以翻看本专题的前面三篇文章。具体函数设计为:
view source print?
01 | /* 初始条件: 串S,T和V存在,T是非空串(此函数与串的存储结构无关) */ |
02 | /* 操作结果: 用V替换主串S中出现的所有与T相等的不重叠的子串 */ |
03 | Status Replace(String S,String T,String V) |
04 | { |
05 | int i=1; /* 从串S的第一个字符起查找串T */ |
06 | if (StrEmpty(T)) /* T是空串 */ |
07 | return ERROR; |
08 | do |
09 | { |
10 | i=Index(S,T,i); /* 结果i为从上一个i之后找到的子串T的位置 */ |
11 | if (i) /* 串S中存在串T */ |
12 | { |
13 | StrDelete(S,i,StrLength(T)); /* 删除该串T */ |
14 | StrInsert(S,i,V); /* 在原串T的位置插入串V */ |
15 | i+=StrLength(V); /* 在插入的串V后面继续查找串T */ |
16 | } |
17 | } while (i); |
18 | return OK; |
19 | } |
完整的可执行程序:
view source print?
001 | #include "stdio.h" |
002 | #include "string.h" |
003 | #include "stdlib.h" |
004 |
005 | #define OK 1 |
006 | #define ERROR 0 |
007 | #define TRUE 1 |
008 | #define FALSE 0 |
009 |
010 | #define MAXSIZE 40 /* 存储空间初始分配量 */ |
011 |
012 | typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */ |
013 | typedef char String[MAXSIZE+1]; /* 0号单元存放串的长度 */ |
014 |
015 | /* 输出字符串T */ |
016 | void StrPrint(String T) |
017 | { |
018 | int i; |
019 | for (i=1;i<=T[0];i++) |
020 | printf ( "%c" ,T[i]); |
021 | printf ( "\n" ); |
022 | } |
023 |
024 | /* 若S为空串,则返回TRUE,否则返回FALSE */ |
025 | Status StrEmpty(String S) |
026 | { |
027 | if (S[0]==0) |
028 | return TRUE; |
029 | else |
030 | return FALSE; |
031 | } |
032 |
033 | /* 生成一个其值等于chars的串T */ |
034 | Status StrAssign(String T, char *chars) |
035 | { |
036 | int i; |
037 | if ( strlen (chars)>MAXSIZE) |
038 | return ERROR; |
039 | else |
040 | { |
041 | T[0]= strlen (chars); |
042 | for (i=1;i<=T[0];i++) |
043 | T[i]=*(chars+i-1); |
044 | return OK; |
045 | } |
046 | } |
047 |
048 | /* 返回串的元素个数 */ |
049 | int StrLength(String S) |
050 | { |
051 | return S[0]; |
052 | } |
053 |
054 | /* 初始条件: 串S和T存在 */ |
055 | /* 操作结果: 若S>T,则返回值>0;若S=T,则返回值=0;若S < T,则返回值< 0 */ |
056 | int StrCompare(String S,String T) |
057 | { |
058 | int i; |
059 | for (i=1;i<=S[0]&&i<=T[0];++i) |
060 | if (S[i]!=T[i]) |
061 | return S[i]-T[i]; |
062 | return S[0]-T[0]; |
063 | } |
064 |
065 | /* 用T返回S1和S2联接而成的新串。若未截断,则返回TRUE,否则FALSE */ |
066 | Status Concat(String T,String S1,String S2) |
067 | { |
068 | int i; |
069 | if (S1[0]+S2[0]<=MAXSIZE) |
070 | { /* 未截断 */ |
071 | for (i=1;i<=S1[0];i++) |
072 | T[i]=S1[i]; |
073 | for (i=1;i<=S2[0];i++) |
074 | T[S1[0]+i]=S2[i]; |
075 | T[0]=S1[0]+S2[0]; |
076 | return TRUE; |
077 | } |
078 | else |
079 | { /* 截断S2 */ |
080 | for (i=1;i<=S1[0];i++) |
081 | T[i]=S1[i]; |
082 | for (i=1;i<=MAXSIZE-S1[0];i++) |
083 | T[S1[0]+i]=S2[i]; |
084 | T[0]=MAXSIZE; |
085 | return FALSE; |
086 | } |
087 | } |
088 |
089 | /* 用Sub返回串S的第pos个字符起长度为len的子串。 */ |
090 | Status SubString(String Sub,String S, int pos, int len) |
091 | { |
092 | int i; |
093 | if (pos < 1||pos>S[0]||len < 0||len>S[0]-pos+1) |
094 | return ERROR; |
095 | for (i=1;i<=len;i++) |
096 | Sub[i]=S[pos+i-1]; |
097 | Sub[0]=len; |
098 | return OK; |
099 | } |
100 |
101 | /* 返回子串T在主串S中第pos个字符之后的位置。若不存在,则函数返回值为0。 */ |
102 | /* 其中,T非空,1≤pos≤StrLength(S)。 */ |
103 | int Index(String S, String T, int pos) |
104 | { |
105 | int i = pos; /* i用于主串S中当前位置下标值,若pos不为1,则从pos位置开始匹配 */ |
106 | int j = 1; /* j用于子串T中当前位置下标值 */ |
107 | while (i <= S[0] && j <= T[0]) /* 若i小于S的长度并且j小于T的长度时,循环继续 */ |
108 | { |
109 | if (S[i] == T[j]) /* 两字母相等则继续 */ |
110 | { |
111 | ++i; |
112 | ++j; |
113 | } |
114 | else /* 指针后退重新开始匹配 */ |
115 | { |
116 | i = i-j+2; /* i退回到上次匹配首位的下一位 */ |
117 | j = 1; /* j退回到子串T的首位 */ |
118 | } |
119 | } |
120 | if (j > T[0]) |
121 | return i-T[0]; |
122 | else |
123 | return 0; |
124 | } |
125 |
126 | /* 初始条件: 串S和T存在,1≤pos≤StrLength(S)+1 */ |
127 | /* 操作结果: 在串S的第pos个字符之前插入串T。完全插入返回TRUE,部分插入返回FALSE */ |
128 | Status StrInsert(String S, int pos,String T) |
129 | { |
130 | int i; |
131 | if (pos< 1||pos>S[0]+1) |
132 | return ERROR; |
133 | if (S[0]+T[0]<=MAXSIZE) |
134 | { /* 完全插入 */ |
135 | for (i=S[0];i>=pos;i--) |
136 | S[i+T[0]]=S[i]; |
137 | for (i=pos;i < pos+T[0];i++) |
138 | S[i]=T[i-pos+1]; |
139 | S[0]=S[0]+T[0]; |
140 | return TRUE; |
141 | } |
142 | else |
143 | { /* 部分插入 */ |
144 | for (i=MAXSIZE;i<=pos;i--) |
145 | S[i]=S[i-T[0]]; |
146 | for (i=pos;i < pos+T[0];i++) |
147 | S[i]=T[i-pos+1]; |
148 | S[0]=MAXSIZE; |
149 | return FALSE; |
150 | } |
151 | } |
152 |
153 | /* 初始条件: 串S存在,1≤pos≤StrLength(S)-len+1 */ |
154 | /* 操作结果: 从串S中删除第pos个字符起长度为len的子串 */ |
155 | Status StrDelete(String S, int pos, int len) |
156 | { |
157 | int i; |
158 | if (pos < 1||pos>S[0]-len+1||len < 0) |
159 | return ERROR; |
160 | for (i=pos+len;i<=S[0];i++) |
161 | S[i-len]=S[i]; |
162 | S[0]-=len; |
163 | return OK; |
164 | } |
165 |
166 | /* 初始条件: 串S,T和V存在,T是非空串(此函数与串的存储结构无关) */ |
167 | /* 操作结果: 用V替换主串S中出现的所有与T相等的不重叠的子串 */ |
168 | Status Replace(String S,String T,String V) |
169 | { |
170 | int i=1; /* 从串S的第一个字符起查找串T */ |
171 | if (StrEmpty(T)) /* T是空串 */ |
172 | return ERROR; |
173 | do |
174 | { |
175 | i=Index(S,T,i); /* 结果i为从上一个i之后找到的子串T的位置 */ |
176 | if (i) /* 串S中存在串T */ |
177 | { |
178 | StrDelete(S,i,StrLength(T)); /* 删除该串T */ |
179 | StrInsert(S,i,V); /* 在原串T的位置插入串V */ |
180 | i+=StrLength(V); /* 在插入的串V后面继续查找串T */ |
181 | } |
182 | } while (i); |
183 | return OK; |
184 | } |
185 |
186 | int main() |
187 | { |
188 | int i, j, opp, pos; |
189 | char s, str; |
190 | String t,s1,s2,sub; |
191 | Status k; |
192 |
193 | printf ( "\n1.StrAssign 生成串 \n2.StrLength 求串长 \n3.StrCompare 串比较 " ); |
194 | printf ( "\n4.Concat 串连接 \n5.SubString 求子串 \n6.Index 求子串位置" ); |
195 | printf ( "\n7.StrInsert 子串插入 \n8.StrDelete 子串删除 \n9.Replace 子串替换" ); |
196 | printf ( "\n0.退出 \n请选择你的操作:\n" ); |
197 | while (opp != ‘0‘ ) |
198 | { |
199 | scanf ( "%d" ,&opp); |
200 | switch (opp) |
201 | { |
202 | case 1: |
203 | k=StrAssign(s1, "nowamagic.net" ); |
204 | if (!k) |
205 | { |
206 | printf ( "串长超过MAXSIZE(=%d)\n" ,MAXSIZE); |
207 | exit (0); |
208 | } |
209 | printf ( "串s1为:" ); |
210 | StrPrint(s1); |
211 | printf ( "\n" ); |
212 | break ; |
213 |
214 | case 2: |
215 | printf ( "串s1长为%d \n" ,StrLength(s1)); |
216 | break ; |
217 |
218 | case 3: |
219 | k=StrAssign(s2, "google.com" ); |
220 | if (!k) |
221 | { |
222 | printf ( "串长超过MAXSIZE(%d)\n" ,MAXSIZE); |
223 | exit (0); |
224 | } |
225 | printf ( "串s2为:" ); |
226 | StrPrint(s2); |
227 | printf ( "\n" ); |
228 |
229 | i=StrCompare(s1,s2); |
230 | if (i < 0) |
231 | s= ‘ < ‘ ; |
232 | else if (i==0) |
233 | s= ‘=‘ ; |
234 | else |
235 | s= ‘>‘ ; |
236 | printf ( "串s1%c串s2\n" ,s); |
237 | break ; |
238 |
239 | case 4: |
240 | Concat(t,s1,s2); |
241 | StrPrint(t); |
242 | break ; |
243 |
244 | case 5: |
245 | printf ( "求串s1的子串,请输入子串的起始位置: " ); |
246 | scanf ( "%d" , &i); |
247 | printf ( "请输入子串的长度: " ); |
248 | scanf ( "%d" , &j); |
249 | printf ( "起始位置:%d,子串长度:%d\n" , i, j); |
250 | k=SubString(sub,s1,i,j); |
251 | if (k) |
252 | { |
253 | printf ( "子串sub为: " ); |
254 | StrPrint(sub); |
255 | } |
256 | break ; |
257 |
258 | case 6: |
259 | printf ( "主串s1为: " ); |
260 | StrPrint(s1); |
261 | k=StrAssign(sub, "magic" ); |
262 | printf ( "子串sub为: " ); |
263 | StrPrint(sub); |
264 | i=Index(s1,sub,1); |
265 | printf ( "s1的第%d个字母起和sub第一次匹配\n" ,i); |
266 | break ; |
267 |
268 | case 7: |
269 | printf ( "主串s1为: " ); |
270 | StrPrint(s1); |
271 | k=StrAssign(sub, "lol" ); |
272 | printf ( "子串sub为: " ); |
273 | StrPrint(sub); |
274 | printf ( "请输入要插入的位置: " ); |
275 | scanf ( "%d" , &pos); |
276 | StrInsert(s1,pos,sub); |
277 | StrPrint(s1); |
278 | break ; |
279 |
280 | case 8: |
281 | printf ( "从串s1的第pos个字符起,删除len个字符,请输入pos: \n" ); |
282 | scanf ( "%d" , &i); |
283 | printf ( "再输入len: \n" ); |
284 | scanf ( "%d" , &j); |
285 | StrDelete(s1,i,j); |
286 | StrPrint(s1); |
287 | break ; |
288 |
289 | case 9: |
290 | printf ( "主串s1为: " ); |
291 | StrPrint(s1); |
292 | StrAssign(t, "a" ); |
293 | printf ( "串t为:" ); |
294 | StrPrint(t); |
295 | StrAssign(sub, "aa" ); |
296 | printf ( "串sub为:" ); |
297 | StrPrint(sub); |
298 | printf ( "用串s2取代串s1中和串t相同的不重叠的串后,串s1为: " ); |
299 | Replace(s1,t,sub); |
300 | StrPrint(s1); |
301 | break ; |
302 |
303 | case 0: |
304 | exit (0); |
305 | } |
306 | } |
307 | } |
字符串中的子串替换
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。