4.2 C ++ construir la tabla de índice palabra
función de correlación
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);
}
}
## función principal índice Project4.2 palabra 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;
}
archivo txt
- 运行前: BookIdx.txt
Estructuras de datos de ordenador 005
010 Introducción a las estructuras de datos
023 Fundamentos de Estructuras de Datos
034 El diseño y análisis de algoritmos de ordenador
050 Introducción al análisis Numercial
067 Análisis Numercial - Después de ejecutar: BookInfo.txt
variar el tamaño de un carácter de espacio y otros caracteres, por lo que el índice de disposición irregular ISBN