软件实习项目3-文本文件单词的检索与计数--实验准备
实验内容
文本文件中每个单词不包含空格且不跨行,单词由字符序列构成且区分大小写,统计给定单词在文本文件中出现的总次数,检索输出的某个单词出现在文本中的行号、在该行中出现的位置。
设计数据量大的文本,进行子串的查询处理,分析算法运行的时间效率,对所有输出的匹配位置结果进行验证,以证明算法设计和实现的正确性。 用朴素模式匹配算法或KMP算法实现字符串定位;
编程语言的选择
选择编者最熟悉的c++来写。
实验思路(实验设计)
一开始尝试用 char*来存储文本,但是个人感觉有点麻烦,而且当时不会处理换行,于是上网查询,最终觉得用结构体来存储单词,然后建立链表,只需要返回头指针就行了
下面展示一些 内联代码片
。
struct danci
{
char s[20]; //单词
int colum; //所在行号
int n; //第n个单词
struct danci* next;
};
然后再建立链表,将文档的内容读入,遇到回车符colum(行数加1),n(单词再某一行的位置)重置为1。
下面展示一些 内联代码片
。
struct danci* read(struct danci* head)
{
FILE* fp;
if (fopen_s(&fp, "1.txt", "r") != NULL)
{
printf("无法打开此文件\n");
exit(0);
}
struct danci* p, * q;
p = (struct danci*)malloc(sizeof(struct danci));
head = q = p;
char ch;
int col = 1;
int count = 1;
int i = 0;
ch = fgetc(fp);
while (ch != EOF) //从文件读取字符
{
if (ch == '\n') //当遇到‘.’或‘,’的下一字符为换行符
{
ch = fgetc(fp);
count = 1;
col += 1; //行数加一,个数重置一
continue;
}
while (ch != ' ' && ch != ',' && ch != '.' && ch != '\n' && ch != EOF)
{
p->s[i] = ch;
i++;
ch = fgetc(fp);
}
p->s[i] = '\0'; //加结束标志
i = 0;
p->colum = col;
p->n = count;
if (ch == ' ' || ch == ',' || ch == '.')
{
count += 1; //个数加一
}
if (ch == '\n')
{
count = 1;
col += 1; //行数加一,个数重置一
}
if (ch == EOF)
{
break;
}
q = p;
p = (struct danci*)malloc(sizeof(struct danci));
q->next = p;
ch = fgetc(fp);
}
q->next = NULL;
return head;
}
如何查询单词出现次数
用函数遍历链表,一次比对,比对成功次数加1。
下面展示一些 内联代码片
。
下面展示一些
内联代码片`。
void chaxun1(struct danci* head, char* str)
{
int total = 0;
while (head != NULL)
{
if (equal(head->s, str))
total += 1;
head = head->next;
} //遍历整个链表
printf("%s 一共出现 %d 次\n", str, total);
}
如何查询单词位置
下面展示一些 内联代码片
。
还是一次遍历,打印出来,这里没有返回值,匹配成功就直接打印出位置了。
void chaxun2(struct danci* head, char* str)
{
int flag = 0;
while (head != NULL)
{
if (equal(head->s, str))
{
flag = 1;
}
if (flag) {
printf("该单词:%s 出现的位置第%d行第%d个单词\n", str, head->colum, head->n);
flag = 0;
}
head = head->next;
} //遍历整个链表
}