1.10图书关键词的检索*** 【基本要求】 (1)从文件中读入关键词建立关键词索引表或书名。 注意:这里的索引表(即字符串堆的存储方式)要求采用第4章课件中最后的应用举例--图书馆关键字的方式。 (2)主要功能: 检索:输入书名确定与其相关的书号。 入库:输入新书名添加到索引表。 (3)选做:常用词过滤、删除等 【演示结果】(菜单操作) (1)显示从文件读取的内容。 (2)显示索引表中所有关键字及相关书号。 (3)输入书名(多个单词),显示每个关键字相关书号。 (4)输入新书名及书号,显示添加结果。c语言完成,代码框架
时间: 2024-01-01 14:03:28 浏览: 73
好的,以下是一个可能的代码框架,供你参考:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_BOOKS 1000 // 最大书籍数
#define MAX_KEYWORDS 1000 // 最大关键词数
#define MAX_KEYWORD_LENGTH 20 // 最大关键词长度
// 书籍结构体
typedef struct {
char title[MAX_KEYWORD_LENGTH];
char id[MAX_KEYWORD_LENGTH];
} Book;
// 关键词节点结构体
typedef struct keyword_node {
char keyword[MAX_KEYWORD_LENGTH];
struct keyword_node *next;
Book *books;
} KeywordNode;
// 全局变量
KeywordNode *keyword_list = NULL; // 关键词索引表
Book books[MAX_BOOKS]; // 存储所有书籍的数组
int num_books = 0; // 实际书籍数
// 函数声明
void load_books(char *filename);
void add_book(char *title, char *id);
void add_to_keyword_list(char *keyword, Book *book);
void display_books();
void display_keyword_list();
void search(char *query);
// 主函数
int main() {
char choice;
char title[MAX_KEYWORD_LENGTH];
char id[MAX_KEYWORD_LENGTH];
char query[MAX_KEYWORD_LENGTH * MAX_KEYWORDS];
// 读取文件中的数据,建立关键词索引表
load_books("books.txt");
// 显示菜单,等待用户输入选择
while (1) {
printf("请选择操作:\n");
printf("(1) 显示所有书籍\n");
printf("(2) 显示关键词索引表\n");
printf("(3) 搜索\n");
printf("(4) 添加新书籍\n");
printf("(q) 退出\n");
scanf(" %c", &choice);
switch (choice) {
case '1':
display_books();
break;
case '2':
display_keyword_list();
break;
case '3':
printf("请输入查询关键词(多个单词请用空格隔开):\n");
scanf(" %[^\n]", query);
search(query);
break;
case '4':
printf("请输入新书籍的名称:\n");
scanf(" %[^\n]", title);
printf("请输入新书籍的编号:\n");
scanf(" %s", id);
add_book(title, id);
break;
case 'q':
printf("再见!\n");
exit(0);
default:
printf("无效的选择,请重新输入!\n");
}
}
}
// 从文件中读取数据,建立关键词索引表
void load_books(char *filename) {
FILE *fp = fopen(filename, "r");
if (fp == NULL) {
printf("无法打开文件 %s!\n", filename);
exit(1);
}
char title[MAX_KEYWORD_LENGTH];
char id[MAX_KEYWORD_LENGTH];
while (fscanf(fp, "%s %s", title, id) != EOF) {
add_book(title, id);
}
fclose(fp);
}
// 将一本新书添加到书籍数组中,并更新关键词索引表
void add_book(char *title, char *id) {
// 检查是否已经存在该书籍
for (int i = 0; i < num_books; i++) {
if (strcmp(books[i].title, title) == 0) {
printf("该书籍已经存在!\n");
return;
}
}
// 添加新书籍
Book *book = &books[num_books++];
strcpy(book->title, title);
strcpy(book->id, id);
// 将新书籍添加到关键词索引表中
char *token = strtok(title, " ");
while (token != NULL) {
add_to_keyword_list(token, book);
token = strtok(NULL, " ");
}
printf("添加成功!\n");
}
// 将一本书籍添加到指定关键词的书籍链表中
void add_to_keyword_list(char *keyword, Book *book) {
KeywordNode *node = keyword_list;
KeywordNode *prev = NULL;
// 查找关键词节点
while (node != NULL && strcmp(node->keyword, keyword) < 0) {
prev = node;
node = node->next;
}
// 如果关键词节点不存在,则创建一个新的节点
if (node == NULL || strcmp(node->keyword, keyword) > 0) {
KeywordNode *new_node = malloc(sizeof(KeywordNode));
strcpy(new_node->keyword, keyword);
new_node->next = node;
new_node->books = NULL;
if (prev == NULL) {
keyword_list = new_node;
} else {
prev->next = new_node;
}
node = new_node;
}
// 将书籍添加到该关键词的书籍链表中
Book *book_copy = malloc(sizeof(Book));
strcpy(book_copy->title, book->title);
strcpy(book_copy->id, book->id);
book_copy->next = node->books;
node->books = book_copy;
}
// 显示所有书籍
void display_books() {
printf("所有书籍:\n");
printf("编号\t名称\n");
for (int i = 0; i < num_books; i++) {
printf("%s\t%s\n", books[i].id, books[i].title);
}
}
// 显示关键词索引表
void display_keyword_list() {
printf("关键词索引表:\n");
KeywordNode *node = keyword_list;
while (node != NULL) {
printf("%s:", node->keyword);
Book *book = node->books;
while (book != NULL) {
printf("%s ", book->id);
book = book->next;
}
printf("\n");
node = node->next;
}
}
// 搜索书籍
void search(char *query) {
printf("搜索结果:\n");
printf("编号\t名称\n");
int num_results = 0;
// 将查询字符串按照空格分割成多个关键词
char *token = strtok(query, " ");
Book *results = NULL;
while (token != NULL) {
KeywordNode *node = keyword_list;
while (node != NULL && strcmp(node->keyword, token) < 0) {
node = node->next;
}
if (node != NULL && strcmp(node->keyword, token) == 0) {
// 该关键词存在于索引表中,将其书籍链表与当前结果链表取交集
Book *cur_result = node->books;
Book *prev_result = NULL;
while (cur_result != NULL && results != NULL) {
if (strcmp(cur_result->title, results->title) == 0) {
// 该书籍同时包含两个关键词,将其添加到新的结果链表中
Book *new_result = malloc(sizeof(Book));
strcpy(new_result->title, cur_result->title);
strcpy(new_result->id, cur_result->id);
new_result->next = NULL;
if (prev_result == NULL) {
results = new_result;
} else {
prev_result->next = new_result;
}
prev_result = new_result;
} else if (strcmp(cur_result->title, results->title) < 0) {
// 当前结果链表中的书籍不包含该关键词,继续向后查找
cur_result = cur_result->next;
} else {
// 当前结果链表中的书籍已经超过了该关键词的范围,跳出循环
break;
}
}
}
token = strtok(NULL, " ");
}
// 输出结果
Book *result = results;
while (result != NULL) {
printf("%s\t%s\n", result->id, result->title);
result = result->next;
num_results++;
}
if (num_results == 0) {
printf("未找到相关书籍!\n");
}
}
```
请注意,这只是一个简单的框架,具体实现细节需要根据实际情况进行调整和完善。同时,代码中可能存在一些错误和不足之处,请谨慎使用。
阅读全文