当前位置:   article > 正文

C语言数据结构:串的表示和实现,采用动态分配的链式存储结构(未使用string.h)

C语言数据结构:串的表示和实现,采用动态分配的链式存储结构(未使用string.h)

完整代码:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #define TRUE 1
  4. #define FALSE 0
  5. #define OK 1
  6. #define ERROR 0
  7. #define INFEASIBLE -1
  8. #define OVERFLOW -2
  9. //给int定义别名为status,当函数返回值是为状态码时,可用status作为函数类型,更方便理解
  10. typedef int Status;
  11. //定义串的结构体,采用动态分配的链式存储结构
  12. typedef struct
  13. {
  14. char *ch;//若是非空串根据串长分配存储空间,否则chNULL
  15. int length;//串的长度
  16. }HString;
  17. //生成一个其值等于串常量chars的串T
  18. Status AssignStr(HString *T,char *chars);
  19. //由串S复制得串T
  20. Status CopyStr(HString T,HString *S);
  21. //判断串S是否为空串
  22. Status EmptyStr(HString S);
  23. //返回串S的元素个数,称为串的长度
  24. int LengthStr(HString S);
  25. //比较串S与串T的大小,S>T,返回值大于零,S=T,返回值等于零,S<T,返回值小于零
  26. int CompareStr(HString S,HString T);
  27. //将串S清为空串,并释放所占空间
  28. Status ClearStr(HString *S);
  29. //用串T返回由串S1和串S2联接而成的新串
  30. Status ConcatStr(HString *T,HString S1,HString S2);
  31. //用串Sub返回串S的第pos个字符起长度为len的子串
  32. Status SubStr(HString *Sub,HString S,int pos,int len);
  33. //在串S的第pos个字符前插入串T
  34. Status InsertStr(HString *S,int pos,HString T);
  35. //从串S中删除第pos个字符起长度为len的子串(包括第pos个字符)
  36. Status DeleteStr(HString *S,int pos,int len);
  37. //用串V替换主串S中出现的所有与串T相等的不重叠的子串
  38. Status ReplaceStr(HString *S,HString T,HString V);
  39. //串的模式匹配,返回值为第一次出现的位置,其中子串为T,主串为S
  40. int IndexStr(HString S,HString T,int pos);
  41. int main(){
  42. HString str1,str2;
  43. HString T;
  44. HString Sub;
  45. char chars1[]="Hello,World!";
  46. char chars2[]="ll";
  47. char chars3[]="Helll,World!";
  48. //给三个串赋值
  49. AssignStr(&str1,chars1);
  50. AssignStr(&str2,chars2);
  51. AssignStr(&T,chars3);
  52. printf("str1.ch = %s\n", str1.ch);
  53. printf("str1.length = %d\n",LengthStr(str1));
  54. printf("str2.ch = %s\n", str2.ch);
  55. printf("str2.length = %d\n",LengthStr(str2));
  56. printf("T.ch = %s\n", T.ch);
  57. printf("T.length = %d\n", LengthStr(T));
  58. printf("T是否为空:%d\n",EmptyStr(T));
  59. printf("比较str1与T大小:%d\n",CompareStr(str1,T));
  60. //联接str1和str2为T
  61. ConcatStr(&T,str1,str2);
  62. printf("T.ch = %s\n", T.ch);
  63. printf("T.length = %d\n", LengthStr(T));
  64. printf("T是否为空:%d\n",EmptyStr(T));
  65. //把str2的值复制给T
  66. CopyStr(str2,&T);
  67. printf("------------------\n");
  68. printf("T.ch = %s\n", T.ch);
  69. printf("T.length = %d\n", LengthStr(T));
  70. //用串Sub返回串str的第7个字符起长度为5的子串
  71. SubStr(&Sub, str1,7,5);
  72. printf("Sub.ch = %s\n", Sub.ch);
  73. printf("Sub.length = %d\n", LengthStr(Sub));
  74. printf("Sub是否为空:%d\n",EmptyStr(Sub));
  75. //在串Sub的第2个字符前插入串str2
  76. InsertStr(&Sub,2,str2);
  77. printf("插入后Sub.ch = %s\n", Sub.ch);
  78. printf("插入后Sub.length = %d\n", LengthStr(Sub));
  79. //删除串Sub的第1个字符
  80. DeleteStr(&Sub,1,1);
  81. printf("删除后Sub.ch = %s\n", Sub.ch);
  82. printf("删除后Sub.length = %d\n", LengthStr(Sub));
  83. printf("------------------\n");
  84. //将str1与T进行匹配,str1为主串,T为子串
  85. printf("T.ch = %s\n", T.ch);
  86. printf("T.length = %d\n", LengthStr(T));
  87. printf("str1.ch = %s\n", str1.ch);
  88. printf("str1.length = %d\n",LengthStr(str1));
  89. printf("第一次出现的位置为%d\n", IndexStr(str1,T,1));
  90. //用串Sub替换主串str1中出现的所有与串T相等的不重叠的子串
  91. printf("Sub.ch = %s\n", Sub.ch);
  92. printf("Sub.length = %d\n", LengthStr(Sub));
  93. ReplaceStr(&str1,T,Sub);
  94. printf("str1.ch = %s\n", str1.ch);
  95. printf("str1.length = %d\n",LengthStr(str1));
  96. //清空串T
  97. ClearStr(&T);
  98. printf("------------------\n");
  99. printf("T.ch = %s\n", T.ch);
  100. printf("T.length = %d\n", LengthStr(T));
  101. printf("T是否为空:%d\n",EmptyStr(T));
  102. }
  103. //生成一个其值等于串常量chars的串T
  104. Status AssignStr(HString* T, char* chars)
  105. {
  106. int len = 0;
  107. //求出串chars的长度
  108. while (chars[len] != '\0')
  109. len++;
  110. //多分配一个字节来存储空字符'\0'
  111. T->ch = (char*)malloc((len + 1) * sizeof(char));
  112. if (!T->ch)
  113. exit(OVERFLOW);
  114. //chars中最后一个字符为'\0',在循环中已经添加复制到T中去了
  115. for (int i = 0; i <= len; i++)
  116. T->ch[i] = chars[i];
  117. T->length = len;
  118. return OK;
  119. }
  120. //由串S复制得串T
  121. Status CopyStr(HString S, HString* T)
  122. {
  123. T->ch = (char*)malloc((S.length + 1) * sizeof(char));
  124. if (!T->ch)
  125. exit(OVERFLOW);
  126. for (int i = 0; i <= S.length; i++)
  127. T->ch[i] = S.ch[i];
  128. T->length = S.length;
  129. return OK;
  130. }
  131. //判断串S是否为空串
  132. Status EmptyStr(HString S)
  133. {
  134. if (S.length == 0)
  135. return TRUE;
  136. else
  137. return FALSE;
  138. }
  139. //返回串S的元素个数,称为串的长度
  140. int LengthStr(HString S)
  141. {
  142. return S.length;
  143. }
  144. //比较串S与串T的大小,S>T,返回值大于零,S=T,返回值等于零,S<T,返回值小于零
  145. int CompareStr(HString S, HString T)
  146. {
  147. for (int i = 0; i < S.length && i < T.length; i++)
  148. {
  149. if (S.ch[i] < T.ch[i])
  150. return -1;
  151. else if (S.ch[i] > T.ch[i])
  152. return 1;
  153. }
  154. //如果循环遍历结束前不能判断两串的大小,就比较两串的长度
  155. if (S.length < T.length)
  156. return -1;
  157. else if (S.length > T.length)
  158. return 1;
  159. return 0;
  160. }
  161. //将串S清为空串,并释放所占空间
  162. Status ClearStr(HString* S)
  163. {
  164. if (S->ch)
  165. {
  166. free(S->ch);
  167. S->ch = NULL;
  168. }
  169. S->length = 0;
  170. return OK;
  171. }
  172. //用串T返回由串S1和串S2联接而成的新串
  173. Status ConcatStr(HString* T, HString S1, HString S2)
  174. {
  175. T->ch = (char*)malloc((S1.length + S2.length + 1) * sizeof(char));
  176. if (!T->ch)
  177. exit(OVERFLOW);
  178. for (int i = 0; i < S1.length; i++)
  179. T->ch[i] = S1.ch[i];
  180. //i <= S2.length这里加等于号是因为要把S2中的'\0'添加到T中
  181. for (int i = 0; i <= S2.length; i++)
  182. T->ch[S1.length + i] = S2.ch[i];
  183. T->length = S1.length + S2.length;
  184. return OK;
  185. }
  186. //用串Sub返回串S的第pos个字符起长度为len的子串
  187. Status SubStr(HString* Sub, HString S, int pos, int len)
  188. {
  189. //判断pos与len的值是否合法,S.length - pos并没有算上第pos个字符,所以在判断时要再加上1
  190. if (pos < 1 || pos > S.length || len < 0 || len > S.length - pos + 1)
  191. return ERROR;
  192. Sub->ch = (char*)malloc((len + 1) * sizeof(char));
  193. if (!Sub->ch)
  194. exit(OVERFLOW);
  195. for (int i = 0; i < len; i++)
  196. Sub->ch[i] = S.ch[pos - 1 + i];
  197. Sub->ch[len] = '\0';
  198. Sub->length = len;
  199. return OK;
  200. }
  201. //在串S的第pos个字符前插入串T
  202. Status InsertStr(HString* S, int pos, HString T)
  203. {
  204. if (pos < 1 || pos > S->length + 1)
  205. return ERROR;
  206. //重新分配存储空间
  207. S->ch = (char*)realloc(S->ch, (S->length + T.length + 1) * sizeof(char));
  208. if (!S->ch)
  209. exit(OVERFLOW);
  210. //把第pos个字符及之后的字符往后移动T.length
  211. for (int i = S->length - 1; i >= pos - 1; i--)
  212. S->ch[i + T.length] = S->ch[i];
  213. //在第pos个字符前插入串T
  214. for (int i = 0; i < T.length; i++)
  215. S->ch[pos - 1 + i] = T.ch[i];
  216. S->length += T.length;
  217. return OK;
  218. }
  219. //从串S中删除第pos个字符起长度为len的子串(包括第pos个字符)
  220. Status DeleteStr(HString* S, int pos, int len)
  221. {
  222. if (pos < 1 || pos >= S->length || len <= 0 || len > S->length - pos + 1)
  223. return ERROR;
  224. //将串S第pos+len个字符后的字符往前移len位
  225. //因为i < S->length,并非<=,所以不能添加'\0'
  226. for (int i = pos - 1 + len; i < S->length; i++)
  227. S->ch[i - len] = S->ch[i];
  228. S->ch = (char*)realloc(S->ch, (S->length - len + 1) * sizeof(char));
  229. if (!S->ch)
  230. exit(OVERFLOW);
  231. S->length -= len;
  232. //最后添加'\0'为串的结束
  233. S->ch[S->length] = '\0';
  234. return OK;
  235. }
  236. //串的模式匹配,返回值为第一次出现的位置,其中子串为T,主串为S
  237. int IndexStr(HString S, HString T, int pos)
  238. {
  239. //T.length > S.length - pos + 1如果T的长度比要比需要进行匹配的剩余字符的长度长,那就不可能匹配成功
  240. if (pos < 1 || pos > S.length || T.length > S.length - pos + 1)
  241. return -1;
  242. //i相当于指向串S的指针,j相当于指向串T的指针
  243. int i = pos - 1;
  244. int j = 0;
  245. while (i < S.length && j < T.length)
  246. {
  247. //继续比较后继字符
  248. if (S.ch[i] == T.ch[j])
  249. {
  250. //如果相等,两串的指针都后移继续比较
  251. i++;
  252. j++;
  253. }
  254. else
  255. {
  256. //如果不相等,串S的指针后移至其本轮匹配开始时i的位置的后一位,串T的指针回到其第一个字符
  257. i = i - j + 1;
  258. j = 0;
  259. }
  260. }
  261. //j >= T.length表示全部匹配成功,就返回成功这次i开始匹配的位置
  262. if (j >= T.length)
  263. return i - T.length + 1;
  264. else
  265. return -1;
  266. }
  267. //用串V替换主串S中出现的所有与串T相等的不重叠的子串
  268. Status ReplaceStr(HString* S, HString T, HString V)
  269. {
  270. //先找出串T第一次出现的位置
  271. int index = IndexStr(*S, T, 1);
  272. //然后对该位置的串进行替换(先删除再插入)
  273. while (index > 0)
  274. {
  275. DeleteStr(S, index, T.length);
  276. InsertStr(S, index, V);
  277. //替换后,再找串T在串S中下一个出现的位置
  278. index = IndexStr(*S, T, index + 1);
  279. }
  280. return OK;
  281. }

运行截图:

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/670447
推荐阅读
相关标签
  

闽ICP备14008679号