目标:通过顺序表存储字符串,并实现计算相似度功能。
但当输入第二个字符串时,原先存储的字符串发生了不可逆的变化
#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
当我在执行完计算相似度后再打印存储的字符串时,发现字符串变了
下图是没有执行计算相似度时打印的存储字符串