鱼C论坛

 找回密码
 立即注册
查看: 1643|回复: 1

哪位大佬可以帮忙改改这代码的问题呢?

[复制链接]
发表于 2023-11-2 19:42:57 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <assert.h>


  5. #define VOLUME 255

  6. typedef struct HString
  7. {
  8.         char* ch;   //指向字符串所在空间地址
  9.         int   length; //记录字符串长度
  10. }HString;

  11. //初始化字符结构
  12. void InitString(HString* S)
  13. {
  14.         S->ch = NULL;
  15.         S->length = 0;
  16. }

  17. //赋值:将字符串str赋给字符结构T
  18. void StrAssign(HString* T, char* str) {
  19.         int i, j, len;
  20.         char* c;
  21.         if (str != NULL) {
  22.                 if (T->ch)
  23.                 {
  24.                         free(T->ch);  //释放T原有的空间
  25.                 }

  26.                 for (len = 0; str[len] != '\0'; len++)
  27.                 {
  28.                         continue;
  29.                 }

  30.                 if (!len) {
  31.                         T->ch = NULL;
  32.                         T->length = 0;
  33.                 }
  34.                 else {
  35.                         T->ch = (char*)malloc((len + 1) * sizeof(char)); // 为null终止符分配空间
  36.                         if (T->ch == NULL) {
  37.                                 exit(-1);
  38.                         }
  39.                 }

  40.                 for (j = 0; j < len; j++) {
  41.                         T->ch[j] = str[j];//分配成功后,将str中的字符逐个赋给T
  42.                 }
  43.                 T->length = len;//记录此时T的长度
  44.         }
  45. }

  46. //获取next数组
  47. void get_next(HString* T, int* next)
  48. {
  49.         int j = 0;
  50.         int i = 1;
  51.         next[1] = 0;

  52.         while (i < T->length)
  53.         {
  54.                 if (0 == j || T->ch[i] == T->ch[j])
  55.                 {
  56.                         i++;
  57.                         j++;
  58.                         if (T->ch[i] != T->ch[j])
  59.                         {
  60.                                 next[i] = j;
  61.                         }
  62.                         else
  63.                         {
  64.                                 next[i] = next[j];
  65.                         }
  66.                 }
  67.                 else
  68.                 {
  69.                         j = next[j];
  70.                 }
  71.         }
  72. }

  73. // 返回子串T在主串S第pos个字符之后的位置
  74. // 若不存在,则返回-1
  75. int Index_KMP(HString* S, HString* T, int pos)
  76. {
  77.         int i = pos;
  78.         int j = 1;
  79.         int *next;

  80.         next = (int*)malloc(sizeof(int) * VOLUME);  //动态分配next数组
  81.         get_next(T, next);

  82.         while (i <= S->length && j <= T->length)
  83.         {
  84.                 if (i <= S->length && (0 == j || S->ch[i] == T->ch[j]))
  85.                 {
  86.                         i++;
  87.                         j++;
  88.                         if (T->ch[i] != T->ch[j])
  89.                         {
  90.                                 next[i] = j;
  91.                         }
  92.                         else
  93.                         {
  94.                                 next[i] = next[j];
  95.                         }
  96.                 }
  97.                 else
  98.                 {
  99.                         j = next[j];
  100.                 }
  101.         }
  102.        
  103.         if (j > T->length)
  104.         {
  105.                 return i - T->length + 1;
  106.         }
  107.         else
  108.         {
  109.                 return -1;
  110.         }
  111.         free(next);
  112. }

  113. int StrCompare(HString *S, HString *T) {
  114.         int i;
  115.         for (i = 0; i < S->length && i < T->length; i++)
  116.         {
  117.                 if (S->ch[i] != T->ch[i])
  118.                 {
  119.                         return S->ch[i] - T->ch[i];
  120.                 }
  121.         }
  122.         return  S->length - T->length;
  123. }

  124. int ClearString(HString* S) {
  125.         if (S->ch)
  126.         {
  127.                 free(S->ch);
  128.                 S->ch = NULL;
  129.         }
  130.         S->length = 0;
  131.         return 0;
  132. }

  133. int main(int argc, char* argv[])
  134. {
  135.         HString input, keyword;
  136.         InitString(&input);
  137.         InitString(&keyword);
  138.        
  139.         if (argc != 3)
  140.         {
  141.                 printf("ERROR_01");
  142.                 exit(-1);
  143.         }

  144.         StrAssign(&input, argv[1]);
  145.         StrAssign(&keyword, argv[2]);

  146.         printf("%d",Index_KMP(&input, &keyword, 0));
  147.         ClearString(&input);
  148.         ClearString(&keyword);
  149.        
  150.         return 0;
  151. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2023-11-2 19:43:29 | 显示全部楼层
这段代码存在以下问题:

1. 在函数 get_next 中,没有对 next 数组进行初始化。应该在函数开始时将 next[0] 初始化为-1。

2. 在函数 Index_KMP 中,动态分配的 next 数组没有在函数结束时释放。应该将 free(next) 放在 return 语句之前。

3. 在函数 StrCompare 中,当字符串长度不相等时,返回的是 S->length - T->length ,这可能导致溢出。应该返回 S->length - T->length 的符号。

4. 在函数 ClearString 中,没有释放 S->ch 指向的内存空间。应该在释放之后将 S->ch 指向 NULL 。

下面是修改后的代码:

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <assert.h>

  5. #define VOLUME 255

  6. typedef struct HString
  7. {
  8.     char* ch;   //指向字符串所在空间地址
  9.     int   length; //记录字符串长度
  10. }HString;

  11. //初始化字符结构
  12. void InitString(HString* S)
  13. {
  14.     S->ch = NULL;
  15.     S->length = 0;
  16. }

  17. //赋值:将字符串str赋给字符结构T
  18. void StrAssign(HString* T, char* str) {
  19.     int i, j, len;
  20.     char* c;
  21.     if (str != NULL) {
  22.         if (T->ch)
  23.         {
  24.             free(T->ch);  //释放T原有的空间
  25.         }

  26.         for (len = 0; str[len] != '\0'; len++)
  27.         {
  28.             continue;
  29.         }

  30.         if (!len) {
  31.             T->ch = NULL;
  32.             T->length = 0;
  33.         }
  34.         else {
  35.             T->ch = (char*)malloc((len + 1) * sizeof(char)); // 为null终止符分配空间
  36.             if (T->ch == NULL) {
  37.                 exit(-1);
  38.             }
  39.         }

  40.         for (j = 0; j < len; j++) {
  41.             T->ch[j] = str[j];//分配成功后,将str中的字符逐个赋给T
  42.         }
  43.         T->ch[j] = '\0'; // 添加字符串结束符
  44.         T->length = len;//记录此时T的长度
  45.     }
  46. }

  47. //获取next数组
  48. void get_next(HString* T, int* next)
  49. {
  50.     int j = 0;
  51.     int i = 1;
  52.     next[0] = -1; // 初始化next数组

  53.     while (i < T->length)
  54.     {
  55.         if (j == -1 || T->ch[ i] == T->ch[j])
  56.         {
  57.             i++;
  58.             j++;
  59.             if (T->ch[ i] != T->ch[j])
  60.             {
  61.                 next[ i] = j;
  62.             }
  63.             else
  64.             {
  65.                 next[ i] = next[j];
  66.             }
  67.         }
  68.         else
  69.         {
  70.             j = next[j];
  71.         }
  72.     }
  73. }

  74. // 返回子串T在主串S第pos个字符之后的位置
  75. // 若不存在,则返回-1
  76. int Index_KMP(HString* S, HString* T, int pos)
  77. {
  78.     int i = pos;
  79.     int j = 0;
  80.     int* next;

  81.     next = (int*)malloc(sizeof(int) * VOLUME);  //动态分配next数组
  82.     get_next(T, next);

  83.     while (i < S->length && j < T->length)
  84.     {
  85.         if (j == -1 || S->ch[ i] == T->ch[j])
  86.         {
  87.             i++;
  88.             j++;
  89.         }
  90.         else
  91.         {
  92.             j = next[j];
  93.         }
  94.     }

  95.     free(next);

  96.     if (j >= T->length)
  97.     {
  98.         return i - T->length;
  99.     }
  100.     else
  101.     {
  102.         return -1;
  103.     }
  104. }

  105. int StrCompare(HString* S, HString* T) {
  106.     int i;
  107.     for (i = 0; i < S->length && i < T->length; i++)
  108.     {
  109.         if (S->ch[ i] != T->ch[ i])
  110.         {
  111.             return (S->ch[ i] > T->ch[ i]) ? 1 : -1;
  112.         }
  113.     }
  114.     return (S->length > T->length) ? 1 : ((S->length < T->length) ? -1 : 0);
  115. }

  116. int ClearString(HString* S) {
  117.     if (S->ch)
  118.     {
  119.         free(S->ch);
  120.         S->ch = NULL;
  121.     }
  122.     S->length = 0;
  123.     return 0;
  124. }

  125. int main(int argc, char* argv[])
  126. {
  127.     HString input, keyword;
  128.     InitString(&input);
  129.     InitString(&keyword);

  130.     if (argc != 3)
  131.     {
  132.         printf("ERROR_01");
  133.         exit(-1);
  134.     }

  135.     StrAssign(&input, argv[1]);
  136.     StrAssign(&keyword, argv[2]);

  137.     printf("%d", Index_KMP(&input, &keyword, 0));
  138.     ClearString(&input);
  139.     ClearString(&keyword);

  140.     return 0;
  141. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-4-22 03:34

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表