Wuhahahaha 发表于 2023-11-2 19:42:57

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

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>


#define VOLUME 255

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

//初始化字符结构
void InitString(HString* S)
{
        S->ch = NULL;
        S->length = 0;
}

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

                for (len = 0; str != '\0'; len++)
                {
                        continue;
                }

                if (!len) {
                        T->ch = NULL;
                        T->length = 0;
                }
                else {
                        T->ch = (char*)malloc((len + 1) * sizeof(char)); // 为null终止符分配空间
                        if (T->ch == NULL) {
                                exit(-1);
                        }
                }

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

//获取next数组
void get_next(HString* T, int* next)
{
        int j = 0;
        int i = 1;
        next = 0;

        while (i < T->length)
        {
                if (0 == j || T->ch == T->ch)
                {
                        i++;
                        j++;
                        if (T->ch != T->ch)
                        {
                                next = j;
                        }
                        else
                        {
                                next = next;
                        }
                }
                else
                {
                        j = next;
                }
        }
}

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

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

        while (i <= S->length && j <= T->length)
        {
                if (i <= S->length && (0 == j || S->ch == T->ch))
                {
                        i++;
                        j++;
                        if (T->ch != T->ch)
                        {
                                next = j;
                        }
                        else
                        {
                                next = next;
                        }
                }
                else
                {
                        j = next;
                }
        }
       
        if (j > T->length)
        {
                return i - T->length + 1;
        }
        else
        {
                return -1;
        }
        free(next);
}

int StrCompare(HString *S, HString *T) {
        int i;
        for (i = 0; i < S->length && i < T->length; i++)
        {
                if (S->ch != T->ch)
                {
                        return S->ch - T->ch;
                }
        }
        returnS->length - T->length;
}

int ClearString(HString* S) {
        if (S->ch)
        {
                free(S->ch);
                S->ch = NULL;
        }
        S->length = 0;
        return 0;
}

int main(int argc, char* argv[])
{
        HString input, keyword;
        InitString(&input);
        InitString(&keyword);
       
        if (argc != 3)
        {
                printf("ERROR_01");
                exit(-1);
        }

        StrAssign(&input, argv);
        StrAssign(&keyword, argv);

        printf("%d",Index_KMP(&input, &keyword, 0));
        ClearString(&input);
        ClearString(&keyword);
       
        return 0;
}

isdkz 发表于 2023-11-2 19:43:29

这段代码存在以下问题:

1. 在函数 get_next 中,没有对 next 数组进行初始化。应该在函数开始时将 next 初始化为-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 。

下面是修改后的代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>

#define VOLUME 255

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

//初始化字符结构
void InitString(HString* S)
{
    S->ch = NULL;
    S->length = 0;
}

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

      for (len = 0; str != '\0'; len++)
      {
            continue;
      }

      if (!len) {
            T->ch = NULL;
            T->length = 0;
      }
      else {
            T->ch = (char*)malloc((len + 1) * sizeof(char)); // 为null终止符分配空间
            if (T->ch == NULL) {
                exit(-1);
            }
      }

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

//获取next数组
void get_next(HString* T, int* next)
{
    int j = 0;
    int i = 1;
    next = -1; // 初始化next数组

    while (i < T->length)
    {
      if (j == -1 || T->ch[ i] == T->ch)
      {
            i++;
            j++;
            if (T->ch[ i] != T->ch)
            {
                next[ i] = j;
            }
            else
            {
                next[ i] = next;
            }
      }
      else
      {
            j = next;
      }
    }
}

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

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

    while (i < S->length && j < T->length)
    {
      if (j == -1 || S->ch[ i] == T->ch)
      {
            i++;
            j++;
      }
      else
      {
            j = next;
      }
    }

    free(next);

    if (j >= T->length)
    {
      return i - T->length;
    }
    else
    {
      return -1;
    }
}

int StrCompare(HString* S, HString* T) {
    int i;
    for (i = 0; i < S->length && i < T->length; i++)
    {
      if (S->ch[ i] != T->ch[ i])
      {
            return (S->ch[ i] > T->ch[ i]) ? 1 : -1;
      }
    }
    return (S->length > T->length) ? 1 : ((S->length < T->length) ? -1 : 0);
}

int ClearString(HString* S) {
    if (S->ch)
    {
      free(S->ch);
      S->ch = NULL;
    }
    S->length = 0;
    return 0;
}

int main(int argc, char* argv[])
{
    HString input, keyword;
    InitString(&input);
    InitString(&keyword);

    if (argc != 3)
    {
      printf("ERROR_01");
      exit(-1);
    }

    StrAssign(&input, argv);
    StrAssign(&keyword, argv);

    printf("%d", Index_KMP(&input, &keyword, 0));
    ClearString(&input);
    ClearString(&keyword);

    return 0;
}
页: [1]
查看完整版本: 哪位大佬可以帮忙改改这代码的问题呢?