秋月琥珀

书名关键词检索程序

这周的周末程序设计(准确来说似乎是上周呐?)
函数部分是老师给的代码,只要写主函数,怪怪的,反正有挺多地方可以吐槽的,而且从学校平台复制下来会给每一行加一个空行,删了两百多行,还会复制出来一些html标签,就很烦,希望老师能改成源文件下载。。。
先放主函数,挺简单的,没多少东西。

int main() {
    InitIdxList(idxlist);\\初始化索引表
    InitWordList(wdlist);\\初始化词表
    FILE* out;
    errno_t m = fopen_s(&out, "D:\\test\\out.txt", "w+");\\结果存储文件
    FILE* f;
    errno_t er = fopen_s(&f, "D:\\test\\c.txt", "r");\\读取文件
    while (feof(f)==0) {
        if (er == 0)GetLine(f);         \\获取一行
        ExtractKeyWord(BookNo);         \\获取书名编号并把关键词存储到此表
        InsIdxList(idxlist, BookNo);    \\把关键词存入索引表
    }
    PutText(out, idxlist);              \\存储结果
}

输入内容

005 Computer Data Structure
010 Introduction to Data Structure
023 Fundamental of Data Structure
034 The Design and Analysis of Computer Algorithms
050 Introduction to Numerical Analysis
067 Numerical Analysis

文件中的输出结果

algorithms          034,
analysis            034,050,067,
computer            005,034,
data                005,010,023,
design              034,
fundamental         023,
introduction        010,050,
numerical           050,067,
structure           005,010,023,

其他函数和定义部分,有些地方因为编译器问题改了一下,太长了
就是IsKey函数里有个严重错误,原来是

    for(i=0; No[i]!=NULL; i++)
        if(!strcmp(No[i],wd))
            return FALSE;
        return TRUE;

但这样当No判断到最后一个并不会停下来,会导致内存访问错误,把for的判断部分改成i<7就行

#include<stdio.h>
#include<malloc.h>
#include<string.h>
#include<ctype.h>

//函数结果状态代码
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2

typedef int Status;
typedef int Boolean;

#define MaxBookNum  1000    // 假设只对 1000 本书建立词索引表
#define MaxKeyNum   2500    // 索引表的最大容量
#define MaxLineLen  500     // 书目串的最大长度
#define MaxWordNum  10      // 词表的最大容量
#define MaxWordLen 100      // 关键词的最大长度

typedef struct {
    char* ch;       // 若是非空串, 则按串长分配存储区, 否则 ch 为 NULL
    int length;     // 串长度
}HString;

typedef struct {
    char* item[MaxWordNum]; // 字符串的数组
    int last;       // 词表的长度
}WordListType;      // 词表类型(顺序表)

typedef int ElemType;   // 定义链表的数据元素类型为整型(书号类型)

typedef struct LNode {
    ElemType data[3];   // 书号(三位数字)
    struct LNode* next; // 指向下一个书号
}*Link, * LinkList;



typedef struct {
    HString key;        // 关键词
    LinkList bnolist;   // 存放书号索引的链表
}IdxTermType;           // 索引项类型



typedef struct {
    IdxTermType item[MaxKeyNum + 1];
    int last;
}IdxListType;   // 索引表类型(有序表)

//主要变量
char* buf;              // 书目串缓冲区
char c[MaxLineLen];
int BookNo[3];  // 书号
char No[7][5] = { "and","of","if","the","to","many","more" };// 常用词表
WordListType wdlist;    // 词表
IdxListType idxlist;    // 索引表

/*
//基本操作
Status StrAssign(HString &T, char* chars);
// 生成一个其值等于串常量 chars 的串 T

int StrCompare(HString S, HString T);
// 若 S>T , 则返回值 >0 ; 若 S=T , 则返回值 =0 ; 若 S<T , </span>则返回值 <0 ;

void StrCopy(HString &S, HString &T);
// 复制 T 到 S

void InitIdxList(IdxListType &idxlist);
// 初始化操作, 置索引表 idxlist 为空表, 且在 idxlist.item[0] 设一空串

Status GetLine(FILE* f);
// 从文件 f 读入一个书目信息到书目串缓冲区 buf

void ExtractKeyWord(ElemType &bno);
// 从 buf 中提取书名关键字到词表 wdlist, 书号存入 bno

Status InsIdxList(IdxListType &idxlist, ElemType bno);
// 将书号为 bno 的书名关键词按词典顺序插入索引表 idxlist

void PutText(FILE g, IdxListType idxlist);
// 将生成的索引表 idxlist 输出到文件 g

Status InitList(LinkList &L);
// 初始化书号索引表为空表

void InitWordList(WordListType &wdlist);
// 初始化词表

Status IsKeyWord(char *wd);
// 判断是否为关键词

Status MakeNode(Link &t,ElemType e[]);
// 初始化新的书号索引结点

Status Appand(LinkList &L,Link s);
// 在关键词后插入新的书号结点

void GetWord(int i, HString &wd);
// 用 wd 返回词表 wdlist 中第 i 个关键词

int Locate(IdxListType idxlist, HString wd, Boolean &b);
// 在索引表 idxlist 中查询是否存在与 wd 相等的关键词。 若存在,则返回其在
// 索引表中的位置, 且 b 取值 TRUE; 否则返回插入位置, 且 b 取值 FALSE

void InsertNewKey(IdxListType &idxlist, int i, HString wd);
// 在索引表 idxlist 的第 i 项上插入新关键词 wd, 并初始化书号索引的链表为空表

Status InsertBook(IdxListType &idxlist, int i, int bno[]);
// 在索引表 idxlist 的第 i 项中插入书号为 bno 的索引
*/

Status StrAssign(HString& T, char* chars) {
    int i;
    char* c;
    if (T.ch)
        free(T.ch);                 // 释放 T 原有的空间
    for (i = 0, c = chars; c != '\0'; i++, c++)
        printf("%c", *c);    // 求 chars 的长度 i
    if (!i) {
        T.ch = NULL;
        T.length = 0;
    }
    else {
        if (!(T.ch = (char*)malloc(i * sizeof(char))))
            return OVERFLOW;
        T.length = i;
        for (i = 0; i < T.length; i++)
            T.ch[i] = chars[i];
        T.ch[i] = '\0';
    }
    return OK;
}// StrAssign

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];
    return S.length - T.length;
}// StrCompare

void StrCopy(HString& S, HString& T) {
    int i;
    if (T.ch == NULL) { S.ch = NULL; S.length = 0; }
    else {
        for (i = 0; i < T.length; i++)
            S.ch[i] = T.ch[i];
        S.ch[i] = '\0';
        S.length = T.length;
    }
}// StrCopy

void GetWord(int i, HString& wd) {
    //  char* p;
    //  p = *(wdlist.item + i); // 取词表中第 i 个字符串
    //  StrAssign(wd, p);       // 生成关键字字符串
    char* t = &(*wdlist.item[i]);
    int n;
    for (n = 0; *t != '\0'; n++)t++;
    wd.length = n;
    for (n = 0; n < wd.length; n++)
        wd.ch[n] = wdlist.item[i][n];
    wd.ch[n] = '\0';
}// GetWord

int Locate(IdxListType& idxlist, HString wd, Boolean& b) {
    int i, m;
    for (i = idxlist.last - 1; (m = StrCompare(idxlist.item[i].key, wd)) > 0; i--);
    if (m == 0) {    // 找到
        b = TRUE;
        return i;
    }
    else {
        b = FALSE;
        return i + 1;
    }
}// Locate

Status InitList(LinkList& L) {
    int i;
    if (!(L = (Link)malloc(sizeof(LNode))))
        return OVERFLOW;
    for (i = 0; i < 3; i++)
        if (!(L->data[i] = (int)malloc(sizeof(int))))
            return OVERFLOW;
    L->next = NULL;
    return OK;
}// InitList

void InsertNewKey(IdxListType& idxlist, int i, HString& wd) {
    int j;
    for (j = idxlist.last - 1; j >= i; j--) {  // 后移索引项
        StrCopy(idxlist.item[j + 1].key, idxlist.item[j].key);
        idxlist.item[j + 1].bnolist = idxlist.item[j].bnolist;
    }
    // 插入新的索引项
    StrCopy(idxlist.item[i].key, wd);   // 串赋值
    InitList(idxlist.item[i].bnolist);  // 初始化书号索引表为空表
    idxlist.last++;
}// InsertNewKey

Status MakeNode(Link& t, ElemType e[]) {
    int i;
    if (!(t = (Link)malloc(sizeof(LNode))))
        return OVERFLOW;
    else for (i = 0; i < 3; i++)
        t->data[i] = e[i];
    t->next = NULL;
    return OK;
}// MakeNode

Status Appand(LinkList& L, Link s) {
    Link q = L;
    if (!s)
        return ERROR;
    while (q->next)
        q = q->next;
    q->next = s;
    return OK;
}// Appand

Status InsertBook(IdxListType& idxlist, int i, int bno[]) {
    Link p;
    if (!MakeNode(p, bno))
        return ERROR;                   // 分配失败
    Appand(idxlist.item[i].bnolist, p); // 插入新的书号索引
    return OK;
}// InsertBook

void Init_HString(HString& wd) {
    wd.ch = (char*)malloc(MaxWordLen * sizeof(char));
    for (int e = 0; e < MaxWordLen; e++)
        wd.ch[e] = '\0';
    wd.length = 0;
}

Status InsIdxList(IdxListType& idxlist, int bno[]) {
    int i, j, b;
    HString wd;
    Init_HString(wd);
    for (i = 0; i < wdlist.last; i++) {
            GetWord(i, wd);
        j = Locate(idxlist, wd, b);
        if (!b)
            InsertNewKey(idxlist, j, wd);   // 插入新的索引项
        if (!InsertBook(idxlist, j, bno))    // 插入书号索引
            return OVERFLOW;
    }
    return OK;
}// InsertIdxList

Status GetLine(FILE* f) {
    int i;
    buf = c;
    if (!feof(f)) {
        for (i = 0; (c[i] = fgetc(f)) != EOF && c[i] != '\n' && i < MaxLineLen; i++);
            c[i] = '\0';
        return OK;
    }
    else return ERROR;
}

void InitWordList(WordListType& wdlist) {
    int i, j;
    for (i = 0; i < MaxWordNum; i++) {
            wdlist.item[i] = (char*)malloc(MaxWordLen * sizeof(char));
        for (j = 0; j < MaxWordLen; j++)
            wdlist.item[i][j] = '\0';
    }
    wdlist.last = 0;
}

Status IsKeyWord(char* wd) {
    int i;
    for (i = 0; i<6; i++)
        if (!strcmp(No[i], wd))
            return FALSE;
    return TRUE;
}

void ExtractKeyWord(int BookNo[3]) {
    int i = 0, j, k;
    char chars[MaxWordLen];
    while (*buf != ' ') {
        BookNo[i] = *buf - '0';
        buf++;
        i++;
    }
    InitWordList(wdlist);
    int m = 0;
    for (i = 0; *buf != '\0' && wdlist.last < MaxWordNum; i++) {
            while (*buf == ' ')
                buf++;
        for (j = 0; *buf != ' ' && *buf != '\0' && *(&(*buf)) != '\n'; j++) {
            //if(isSupper(*buf))
            chars[j] = tolower(*buf);
            //else 
            //  chars[j] = *buf;
            buf++;
        }
        chars[j] = '\0';
        if (IsKeyWord(chars)) {
            for (k = 0; k < j; k++)
                wdlist.item[m][k] = chars[k];
            m++;
            wdlist.last++;
        }
    }
}

void PutText(FILE* g, IdxListType idxlist) {
    int i, j;
    for (i = 0; i < idxlist.last; i++) {
            fprintf(g, "%-20s", idxlist.item[i].key.ch);
        Link t = idxlist.item[i].bnolist->next;
        while (t) {
            for (j = 0; j < 3; j++)
                fprintf(g, "%d", t->data[j]);
            fprintf(g, ",");
            t = t->next;
        }
        fprintf(g, "\n");
    }
}

void InitIdxList(IdxListType& idxlist) {
    int i;
    for (i = 0; i < MaxKeyNum; i++) {
            Init_HString(idxlist.item[i].key);
    }
    InitList(idxlist.item[0].bnolist);
    idxlist.last = 0;
}