c++顺序表实现计算字符串相似度bug

问题遇到的现象和发生背景

目标:通过顺序表存储字符串,并实现计算相似度功能。
但当输入第二个字符串时,原先存储的字符串发生了不可逆的变化

部分代码
#include 
using namespace std;

#define LIST_INIT_SIZE 1000
#define LISTINCREMENT 10
#define OK 1
#define OVERFLOW 0
#define ERROR -1
#define MAXLEN 10

#include 
#include 
#include 
#include 
#include 

typedef char *ElemType;

typedef struct
{
    char *elem;
    int *idx;
    int length;
    int listsize;
} ElemType2;
typedef int Status;

typedef struct
{
    ElemType *elem;
    int length;
    int listsize;
} SqList;

typedef struct
{
    ElemType2 *count;
    int length;
    int listsize;
} CtList;

//基础功能

Status InitList(SqList &L)
{
    L.elem = (ElemType *)malloc(LIST_INIT_SIZE * sizeof(ElemType));
    if (!L.elem)
    {
        cout << "fail to initialize";
        exit(OVERFLOW);
    }
    L.length = 0;
    L.listsize = LIST_INIT_SIZE;
    return OK;
}

Status InitCount(ElemType2 &L)
{
    L.idx = (int *)malloc(LIST_INIT_SIZE * sizeof(int));
    if (!L.idx)
    {
        cout << "fail to initialize";
        exit(OVERFLOW);
    }
    L.elem = (char *)"";
    L.length = 0;
    L.listsize = LIST_INIT_SIZE;
    return OK;
}

Status InitList2(CtList &L)
{
    L.count = (ElemType2 *)malloc(LIST_INIT_SIZE * sizeof(ElemType2));
    InitCount(*L.count);
    if (!L.count)
    {
        cout << "fail to initialize";
        exit(OVERFLOW);
    }
    L.length = 0;
    L.listsize = LIST_INIT_SIZE;
    return OK;
}

Status ListInsert(SqList &L, int i, ElemType e)
{
    if (L.length == L.listsize)
    {
        ElemType *newbase;
        newbase = (ElemType *)realloc(L.elem, (L.listsize + LISTINCREMENT) * sizeof(ElemType));
        if (!newbase)
            exit(OVERFLOW);
        L.elem = newbase;
        L.listsize += LISTINCREMENT;
    }
    if (i < 1 || i > L.length + 1)
        return ERROR;

    ElemType *q;
    q = &L.elem[i - 1];
    for (ElemType *p = &L.elem[L.length - 1]; p >= q; --p)
    {
        *(p + 1) = *p;
    }

    *q = e;
    ++L.length;
    return OK;
}

Status ElemInsert(CtList &L, ElemType e)
{
    if (L.length == L.listsize)
    {
        ElemType2 *newbase;
        newbase = (ElemType2 *)realloc(L.count, (L.listsize + LISTINCREMENT) * sizeof(ElemType2));
        if (!newbase)
            exit(OVERFLOW);
        L.count = newbase;
        L.listsize += LISTINCREMENT;
    }

    L.count[L.length].elem = e;
    ++L.length;
    return OK;
}

Status CountInsert(ElemType2 &L, int e)
{
    if (L.length == L.listsize)
    {
        int *newbase;
        newbase = (int *)realloc(L.elem, (L.listsize + LISTINCREMENT) * sizeof(int));
        if (!newbase)
            exit(OVERFLOW);
        L.idx = newbase;
        L.listsize += LISTINCREMENT;
    }

    L.idx[L.length] = e;
    ++L.length;
    return OK;
}

Status DestroyList(SqList &L)
{
    free(L.elem);
    L.elem = NULL;
    L.length = 0;
    L.listsize = 0;
    return OK;
}

Status DestroyCtList(CtList &L)
{
    free(L.count);
    L.count = NULL;
    L.length = 0;
    L.listsize = 0;
    return OK;
}

//附加功能

Status CountElem(SqList &L, CtList &L2, ElemType e)
{
    for (int j = 0; j < L.length - 1; j++) //遍历整个顺序表,和e值一一作比较,
    {
        char *item = L.elem[j];
        if (strcmp(item, e) == 0)
        {
            CountInsert(*L2.count, j);
        }
    }
    return OK;
}

Status CountList(SqList &L, CtList &L2) //词频统计
{
    for (int i = 0; i < L.length - 1; i++) //遍历整个顺序表
    {
        bool find = false;
        char *item = L.elem[i];
        for (int j = 0; j < L2.length; j++)
        {
            if (strcmp(item, L2.count[j].elem) == 0)
            {
                CountInsert(L2.count[j], i);
                find = true;
            }
        }
        if (!find)
        {
            InitCount(L2.count[L2.length]);
            ElemInsert(L2, item);
            CountInsert(L2.count[L2.length - 1], i);
        }
    }
    return OK;
}

float CountSim(CtList &L1, CtList &L2)
{
    int score1 = 0;
    for (int i = 0; i < L1.length; i++)
    {
        char *item;
        item = L1.count[i].elem;
        for (int j = 0; j < L2.length; j++)
        {
            if (strcmp(item, L2.count[j].elem) == 0)
            {
                score1 += L1.count[i].length * L2.count[j].length;
                break;
            }
        }
    }

    int score2 = 0;
    for (int i = 0; i < L1.length; i++)
    {
        score2 += L1.count[i].length * L1.count[i].length;
    }

    int score3 = 0;
    for (int i = 0; i < L2.length; i++)
    {
        score3 += L2.count[i].length * L2.count[i].length;
    }

    float score4;
    float score5;
    float score;
    score4 = sqrt((float)score2);
    score5 = sqrt((float)score3);

    score = (float)score1 / (score4 * score5);

    return score;
}


//输出功能

void OutPutList(SqList &L)
{
    cout << "字符串:";
    for (int i = 0; i < L.length - 2; i++)
    {
        cout << L.elem[i] << ", ";
    }
    cout << L.elem[L.length - 2] << endl;
}

void OutPutRequest()
{
    cout << "打印存储单词请按1" << endl;
    cout << "倒置单词请按2" << endl;
    cout << "判断回文请按3" << endl;
    cout << "计算单词个数请按4" << endl;
    cout << "查找单词请按5" << endl;
    cout << "词频统计请按6" << endl;
    cout << "字符串合并请按7" << endl;
    cout << "计算字符串相似度请按8" << endl;
    cout << "销毁字符串请按9" << endl;
    cout << "插入字符串请按10" << endl;
    cout << "删除字符串请按11" << endl;
    cout << "删除指定位置字符串请按12" << endl;
}

int main()
{
    SqList L;
    InitList(L);
    char str[MAXLEN * LIST_INIT_SIZE] = "\0";
    cout << "请输入字符串:";
    gets(str);
    for (int i = 0; i < strlen(str); i++)
    {
        if (str[i] == ',' || str[i] == '.')
        {
            str[i] = ' ';
        }
    }
    
    char *str1 = strtok(str, " ");
    
    ListInsert(L, 1, str1);
    for (int i = 2; str1 != NULL; i++)
    {
        str1 = strtok(NULL, " ");
        ListInsert(L, i, str1);
    }

    char str2[20] = "\0";
    char str3[20] = "\0";
    char *str4;
    char str5[20] = "\0";
    char *str6;
    char str7[20] = "\0";
    char *str8;
    CtList L2;
    SqList L3;
    CtList L4;
    int idx;
    bool end = false;
    int length;

    while (!end)
    {
        cout << endl;
        OutPutRequest();
        int req;
        cin >> req;
        switch (req)
        {
        case 1:
            OutPutList(L);
            break;
        case 8:
            InitList2(L2);
            CountList(L, L2);   

            cout << "请输入要计算相似度的字符串:";
            getchar();
            gets(str5);

            InitList(L3);
            str6 = strtok(str5, " ");
            ListInsert(L3, 1, str6);
            for (int i = 2; str6 != NULL; i++)
            {
                str6 = strtok(NULL, " ");
                ListInsert(L3, i, str6);
            }

            InitList2(L4);
            CountList(L3, L4);

            cout << endl;

            cout << CountSim(L2, L4);
            break;

        default:
            DestroyList(L);
            end = true;
            break;
        }        
    }
    return 0;
}
运行结果及报错内容

当我复制粘贴同一串字符串时,相似度结果并不是1

img

当我在执行完计算相似度后再打印存储的字符串时,发现字符串变了

img

下图是没有执行计算相似度时打印的存储字符串

img

求问如何解决这个bug!
不知道你这个问题是否已经解决, 如果还没有解决的话:

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^