文学研究助手(kmp改进算法)c实现

要求

统计某篇英文小说中某些特定单词的出现次数和位置(行号和列号)。
要求建立一个文本文件,存储一篇英文小说的片段,每个单词不包含空格,且不跨行。单词由字符序列构成,且区分大小写;检索输出给定单词出现在文本中的行号,以及在该行中出现的位置(列号);统计给定单词在文本文件中出现的总次数。
使用改进的KMP匹配算法,实现字符串的模式匹配问题。
本程序应包括主程序模块查找模块、功能模块。
本系统也可采用单链表存储结构来实现。

关键要点

KMP匹配算法
仅后移模式串,比较指针不回溯
=>公共前后缀
原理:子串移动到公共前后缀+1的位置与主串当前位比较
Next数组求值
next保存每个串的公共前后缀,值即为公共前后缀
优点:避免比较指针回溯,提高效率

源码如下

代码并未涉及到太多数据结构内容 用二维数组更加方便

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int  keynum;//关键词数量
char *readbuf;//读入缓冲区(用来读写所存的文件) 
int  hang,lie;//确定行和列 

int length(char *p){   //求字符串长度 
	int i=1;
	while(p[i]){
		i++;
	}
	return i-1;
}

int* get_next(char *p,int *next){ //求next数组 
	int i,k;
    i=1,k=0;
    next[1]=0; 
    while(i<length(p)){ 
    	if(k==0||p[i]==p[k]){
    		++i;
    		++k;
    		if(p[i]!=p[k]){
    		next[i]=k;}
    		else{
    		  next[i] = next[k];
			}
		}
		else{
			k=next[k];
		}
	}
	return next;
}

int Index(char *S,char *P,int pos,int *next) //KMP算法
{
	int i=pos,j=1;
   	while(i<=length(S)&&j<=length(P))
   	{
    	if(j==0||S[i]==P[j])
		{
			++i;
			++j;
		} 
    	else
    	{
    		j=next[j];
		}
   	}
   if(j>length(P))
    {
   		return (i-length(P));
	} 
    else
    {
    	return 0;
	}
}


int main()
{
  int i,j;
  char **p;
  int  **next;
  int  **pnext;
  printf("*******************欢迎使用文学助手系统**************************\n");
  while(1){
  printf("请输入你需要查询的关键词数量\n");
  scanf("%d",&keynum);
  p    =    (char**)malloc(sizeof(char*)*keynum);//动态开辟二维数组 用来保存字符串 
  next =    (int**) malloc(sizeof(int*)*keynum);//动态开辟二维数组  用来保存每个字符串的next数组 
  pnext =   (int**) malloc(sizeof(int*)*keynum);//用来承接函数返回值 
  for(i=0;i<keynum;i++){
  	next[i] = (int*)malloc(sizeof(int)*20);
  }
  for(i=0;i<keynum;i++){
  	pnext[i] = (int*)malloc(sizeof(int)*20);
  }
  for(i=0;i<keynum;i++){
  	p[i] = (char *)malloc(sizeof(char)*20);
  }
  printf("请输入你需要查询的关键词\n");
  for(i=0;i<keynum;i++){
  	scanf("%s",&p[i][1]);                //输入字符串 
  }
  printf("你所查询的关键词如下:\n");
  for(i=0;i<keynum;i++){
  	printf("%s",&p[i][1]);               //查询字符串 
  	printf("\n");
  }
  for(i=0;i<keynum;i++){
     pnext[i] = get_next(p[i],next[i]);
     printf("%s的next数组为:",&p[i][1]);
     for(j=1;j<strlen(p[i]);j++){
     	 printf("%d ",pnext[i][j]);
	 }
	 printf("\n");
  }
  readbuf = malloc(sizeof(char)*1024);
  for(i=0;i<keynum;i++){
  	    int row=0,col =0;
  	    int k=0;
  	    int count = 0;
  	  	FILE *fp;                           //创建一个文件 
	  	fp=fopen("1.txt","r");
	  	if(fp==NULL){
			printf("open file\n");
		}
	  while(!feof(fp)){
	  	fgets(readbuf,1024,fp);
	  	row++;
  	 	col = Index(readbuf,p[i],0,next[i]);   //返回文件的列 
  	 	if(col!=0){
  	 	  printf("%s的行为%d,列为%d",&p[i][1],row,col+1);
  	 	  k++;
		}
		while(col!=0){
			col = Index(readbuf,p[i],col+1,next[i]);
			if (col!=0)         
	    	{
				k++;
				printf(",%d",col+1);//若匹配成功,则打印列号
		    }else{
		    	printf("\n");
			}
		 }
  	}
	   	count=count+k;
//	   	if (k) 
//	   	{
//		   	printf("\n"); //输出格式控制	
//		}
		fclose(fp);	
	    if(count){
		 printf("%s共出现%d次\n",&p[i][1],count);
		 printf("\n");
	  } 
	 else{
		 printf("No Found\n");
		 printf("\n"); 
	 }
	}
  }
  
}
 

实验效果

在这里插入图片描述
实验中所用的文本文件,写出代码后可自行实验
注意:在创建文本文件后,重命名时直接命名为想要的名字就好。不需要带.txt后缀。
例如 创建一个名字为1的文本文件 直接命名为1
如果加txt后缀名字就会变为 1.txt.txt

4 Making a friend
The next morning we got up in the dark as before, but the water was frozen, so we could not wash. It was freezing cold in all the rooms. This time the porridge was not burnt,but I still felt hungry, as the quantity was so small.
I stayed in the bottom class, but noticed the girl that I had been talking to was in another class. Her surname seemed to be Burns. Teachers called girls by their surnames in this school. Her class were studying history, and her teacher,Miss Scatcherd, appeared constantly annoyed by her.
‘Burns, hold your head up, can’t you!’
'Burns,don’t stand like that!’
The history questions asked by Miss Scatcherd sounded very difficult, but Burns knew all the answers. I kept expecting the teacher to praise her,but instead she suddenly cried out,
'You dirty girl!You haven’t washed your hands this morning!’
I was surprised that Burns did not explain that none of us could wash our faces or hands because the water had been frozen. Miss Scatcherd gave an order. Burns left the room and returned, carrying a stick. The teacher took it and hit Burns several times with it. The girl did not cry or change her expression.
"Wicked girl!'said Miss Scatcherd. 'Nothing will change your dirty habits!
Later that day, during the play-hour, I found Burns alone by the fireside,reading the same book as before, and I started talking to her.
'What is the rest of your name?'I asked.
'Helen,'she replied.
‘Do you want to leave Lowood?’
'No, why should 1? I was sent to school here,so I must learn as much as I can. 'But Miss Scatcherd is so cruel to you! 'I burst out.
'Cruel? Not at all. She is strict and she sees my faults.
'If I were you, I’d hate her, 'I cried.'If she hit me with a stick, I’d seize it and break it under her nose.
'I don’t think you would,'answered Helen quietly. 'And if you did,Mr Brocklehurst would send you away from school, and your relations would be upset. Anyway, the Bible tells us to do good, even if other people hurt us. Sometimes you have to put up with some hard things in life. "
I could not understand her ideas but I had a feeling she might be right. I looked at her in wonder.
You say you have faults, Helen. What are they? To me you seem very good.
'You are wrong, 'she answered. 'I’m untidy and careless and I forget the rules. I read when I should be doing my homework. You see, Miss Scatcherd is right to scold me.
'Is Miss Temple as strict as that? 'I asked.
A soft smile passed over Helen’s normally serious face.
'Miss Temple is full of goodness. She gently tells me of my mistakes,and praises me if I do well. But even with her help I don’t concentrate properly in class, I just dream away the time, and then I can’t answer the teacher’s questions.
'But today in history you knew all the answers!'I said.
'I just happened to be interested,that’s all,'she replied.
‘I expect you are always interested in Miss Temple’s lessons,because you like her and she is good to you. I’m like that. I love those who love me,and I hate those who punish me unfairly.’ 'You should read the Bible and do what Christ says—people who believe in God should love their enemies,'said Helen.
'Then I should love Mrs Reed and her son John,which is impossible,'I cried.
Helen asked me to explain what I meant, and listened carefully to the long story of what I had suffered at Gateshead.
'Well, 'I asked impatiently at the end, ‘isn’t Mrs Reed a bad woman? Don’t you agree with me?’
‘It’s true she has been unkind to you, because she dislikes your faults, as Miss Scatcherd dislikes mine. But look how bitterly you remember every angry word ! Wouldn’t you be happier if you tried to forget her scolding? Life is too short to continue hating anyone for a long time. We all have faults, but the time will come soon when we die,when our wickedness will pass away with our bodies,leaving only the pure flame of the spirit.That’s why I never think of revenge,I never consider life unfair. I live in calm, looking forward to the end.’
For a moment we both stayed silent. Then one of the big girls came up, calling, 'Helen Burns! Go and put away your work and tidy your drawer immediately,or I’ll tell Miss scatcherd! ’
Helen sighed, and, getting up, silently obeyed.

  • 10
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

pg_hj

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值