建立词索引表

4.2建立词索引表C++

相关函数

listLink.h

// - - - - - 线性表的有序链表存储结构(升序) - - - - -
typedef struct LNode {
	ElemType data;
	struct LNode* next;
}*Link;
typedef struct {		//链表类型
	Link head, tail;	//分别指向线性链表中的头结点(第0个)和最后一个结点
	int len;			//指示线性链表中数据元素的个数
}LinkList;

// - - - - - 基本操作的函数原型说明 - - - - -
Status MakeNode(Link& p, ElemType e);
//分配由p指向的值为e的结点,并返回true;若分配失败,则返回false
Status InitList(LinkList& L);
//构造一个空的线性链表L
Status Append(LinkList& L, Link s);
//将指针s所指(彼此以指针相连)的一串结点链接在线性链表L的最后一个结点
//之后,并改变链表L的尾指针指向新的尾结点

// - - - - - 基本操作的算法描述 - - - - -
Status MakeNode(Link& p, ElemType e) {
	if (!(p = (Link)malloc(sizeof(LNode))))
		return false;
	p->data = e;
	p->next = NULL;
	return true;
}

Status InitList(LinkList& L) {
	L.head = L.tail = (Link)malloc(sizeof(LNode));
	if (!L.head) exit(OVERFLOW);
	L.head->next = NULL;
	L.len = 0;
	return true;
}

Status Append(LinkList& L, Link s) {
	int i = 1;
	L.tail->next = s;
	while (s->next) {
		s = s->next;
		i++;
	}
	L.tail = s;
	L.len += i;
	return true;
}

string.h

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

// - - - - - 基本操作的函数原型说明 - - - - -
Status StrAssign(HString& T, char* chars);
	//生成一个其值等于串常量chars的串T
Status StrCopy(HString& T, HString S);
	//用T返回串S,串的复制
int StrCompare(HString S, HString T);
	//若S>T,返回值>0;若S=T,返回值=0;若S<T,返回值<0

// - - - - - 基本操作的算法描述 - - - - -
Status StrAssign(HString& T, char* chars) {
//	if (T.ch) free(T.ch);	//释放T的原有空间
	int len = strlen(chars);//求chars的长度L
	if (!len) {
		T.ch = NULL; T.length = 0;
	}
	else {
		T.ch = NULL;
		if (!(T.ch = (char*)malloc((len + 1) * sizeof(char))))
			exit(OVERFLOW);
		strcpy_s(T.ch, len + 1, chars);	//T.ch[0..i - 1] = chars[0..i - 1];
		T.length = len;
	}
	return true;
}// StrAssign

Status StrCopy(HString& T, HString S) {
//	if (T.ch) free(T.ch);
	T.ch = NULL;
	T.ch = (char*)malloc((S.length + 1) * sizeof(char));
	if (!T.ch) exit(OVERFLOW);
	strcpy_s(T.ch, S.length + 1, S.ch);
	T.length = S.length;
	return true;
}

int StrCompare(HString S, HString T) {
	for (int i = 0; i < S.length && i < T.length; ++i)
		if (S.ch[i] != T.ch[i]) return int(S.ch[i] - T.ch[i]);
	return S.length - T.length;
}// StrCompare

index.h

typedef bool Status;
typedef char* ElemType;	//定义链表的的数据元素类型为字符串(书号类型)
#include "string.h"
#include "listLink.h"
#define MaxBookNum 1000  //假设只对1000本书建立索引表
#define MaxKeyNum 2500   //索引表的最大容量
#define MaxLineLen 500   //书目串的最大长度
#define MaxWordNum 10    //词表的最大容量
#define MaxWordLen 50	 //单词的最大长度

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

typedef struct IdxTermType {
	HString key;					//关键词
	LinkList bnolist;				//存放书号索引的链表
}IdxTermType;						//索引项类型
typedef struct IdxListType {
	IdxTermType item[MaxKeyNum + 1];
	int last;
}IdxListType;						//索引表类型(有序表)

	//主要变量
char buf[MaxLineLen]="\0";			//书目串缓冲区
WordListType wdlist;				//词表

	//基本操作
void InitIdxList(IdxListType& idxlist);
//初始化操作,置索引表idxlist为空表,且在idxlist.item[0]设一空串
void GetLine(FILE* f);
//从文件f读入一个书目信息到书目串缓冲区
void ExtractKeyWord(ElemType& bno, WordListType& wdlist);
//从buf中提取书名关键词到词表wdlist,书号存入bno
Status InsIdxList(IdxListType& idxlist, ElemType bno);
//将书号为bno的书名关键词按词典顺序插入索引表idxlist
void PutText(FILE* g, IdxListType idxlist);
//将生成的索引表idxlist输出到文件g

void InitIdxList(IdxListType& idxlist) {
//	char temp[6][10] = { "a","an","and","of","the","to" };
	char a[2] = "\0";
	StrAssign(idxlist.item[0].key, a);
	idxlist.last = 0;
//	for (int i = 0; i < 10; i++)
//		InitList(idxlist.item[i].bnolist);
}

void GetLine(FILE* f) {
	fgets(buf, MaxLineLen, f);
}

void ExtractKeyWord(ElemType& bno, WordListType& wdlist) {
	int i, k, j; j = k = 0;
	i = wdlist.last - 1;
	while (wdlist.last) {
		memset(wdlist.item[i], 0, sizeof(wdlist.item[i]));
		wdlist.last--; i--;
	}
	i = 0;
	bno = (char*)malloc(5 * sizeof(char));
	while (*(buf + i) != ' ') {
		bno[i] = buf[i];
		i++;
	}
	bno[i] = '\0';
	while (*(buf + i) == ' ') i++;                   //过滤中间的空格
	while (*(buf + i) != '\n' && *(buf + i) != '\0') //开始处理关键词
	{
		if (*(buf + i) != ' ') {
			wdlist.item[j][k] = tolower(*(buf + i));
			i++; k++;
		}
		else{
			wdlist.item[j][k] = '\0';
			while (*(buf + i) == ' ') i++;            //过滤关键词之间的空格
			k = 0; j++;
			wdlist.last++;
		}
	}
	wdlist.item[j][k] = '\0'; //最后字符串收尾         
	wdlist.last++;            //长度加1
}

//实现插入所需操作
void GetWord(int i, HString& wd);
//用wd返回词表wdlist中第i个关键词
int Locate(IdxListType idxlist, HString wd, bool& b);
//在索引表idxlist中查询是否存在与wd相等的关键词。
//若存在,则返回其在索引表的位置,且b取值true;否则返回插入位置,且b取值false
void InsertNewKey(IdxListType& idxlist, int i, HString wd);
//在索引表idxlist的第i项插入新关键词wd,并初始化书号索引的链表为空表
Status InsertBook(IdxListType& idxlist, int i, ElemType bno);
//在索引表idxlist的第i项中插入书号为bno的索引

void GetWord(int i, HString& wd) {
	StrAssign(wd, wdlist.item[i] );	//取词表中第i个字符串,生成关键字字符串
}// GetWord

int Locate(IdxListType idxlist, HString wd, bool& 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;
	}
	b = false;
	return i + 1;
}//Locate

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

Status InsertBook(IdxListType& idxlist, int i, ElemType bno) {
	Link p;
	if (!MakeNode(p, bno))
		return false;
	Append(idxlist.item[i].bnolist, p);
	return true;
}// InsertBook

Status InsIdxList(IdxListType& idxlist, ElemType bno) {
	int i, j; HString wd; bool b;
	for (i = 0; i < wdlist.last; i++) {
		wd.ch = NULL; wd.length = 0;
		GetWord(i, wd);
		j = Locate(idxlist, wd, b);
		if (!b) InsertNewKey(idxlist, j, wd);
		if (!InsertBook(idxlist, j, bno))
			exit(OVERFLOW);
	}
	return true;
}// InsertIdxList

void PutText(FILE* file, IdxListType idxlist) {
	fprintf(file, "%s", "关键词                            书号索引\n");
	for (int i = 0; i < idxlist.last; i++)
	{

		fprintf(file, "%-30s", idxlist.item[i].key.ch);
		Link p = idxlist.item[i].bnolist.head->next;
		while (p){
			fprintf(file, "%s", p->data);
			p = p->next;
			if(p) fputc(',', file);
		}
		fputc('\n', file);
	}
}

##主函数 Project4.2-word index table.cpp

#include <iostream>
using namespace std;
#include "index.h"
#pragma warning(disable:4996)   //去掉使用fopen函数的错误警告

int main(){
	FILE* f, * g;
	IdxListType idxlist;
	ElemType BookNo;
	if (f = fopen("D:\\BookIdx.txt", "r")) {
		if (g = fopen("D:\\BookInfo.txt", "w")) {
			InitIdxList(idxlist);
			while (!feof(f)) {
				GetLine(f);
				ExtractKeyWord(BookNo, wdlist);
				InsIdxList(idxlist, BookNo);
			}
			PutText(g, idxlist);
			fclose(g);
		}
		else
			cout << "无法生成索引表文件!" << endl;
	}
	else
		cout << "打开书目文件失败!" << endl;
	fclose(f);
	return 0;
}

txt文件

  • 运行前:BookIdx.txt
    005 Computer Data Structures
    010 Introduction to Data Structures
    023 Fundamentals of Data Structures
    034 The Design and Analysis of Computer Algorithms
    050 Introduction to Numercial Analysis
    067 Numercial Analysis
  • 运行后:BookInfo.txt
    因空格字符与其他字符大小不同,故书号索引排列不整齐
发布了1 篇原创文章 · 获赞 0 · 访问量 41

猜你喜欢

转载自blog.csdn.net/Xppal/article/details/104801750