简单的利用c++实现 文本文件单词的检索和计数(KMP算法)

主要功能:检索输出某个单词某个单词出现在文本中的行号、在改行中出现的次数以及位置。

核心代码设计:

//设计初始类
class Word
{
public:
	Word(){text[0]='\0';}
	int Getlength()const;
	void PlaceVocabulary();
	char text[MaxStrSize];
	
};

Getlength()为求取text的字符串长度

PlanceVocaBulary()为可使用用户在程序过程中输入字符

1.求取失效函数算法设计

求失效函数的作用是用于KMP算法过程中需要的变量。

它的算法过程如下代码所示:

void GetFailure(const Word &pat,int f[])
{
	int j=0,k=-1;
	f[0]=-1;
	while(j<pat.Getlength()-1)
		if(k==-1||pat.text[k]==pat.text[j])
			f[++j]=++k;
		else
			k=f[k];
}

2.KMP算法设计

int KMP_find(Word ob,Word pat,int p=0)//p是用于下次匹配的开始检索位置
{
	int *f=new int[pat.Getlength()];
	GetFailure(pat,f);
	int i=p,j=0;
	while(i<ob.Getlength()&&j<pat.Getlength()&&pat.Getlength()-j<=ob.Getlength()-i)
	{
		if(j==-1||pat.text[j]==ob.text[i])
		{
			i++;
			j++;
		}
		else
			j=f[j];
	}
	delete []f;
	if(j<pat.Getlength())
		return -1;  
	else
		return i-j;
	
}

3.统计单词出现次数功能设计

void WordCount()
{
	Word ob,pat;
	char filename[10];
	ifstream infile;
	int i=0,j,k;
	cout<<"Place input flie name:";
	cin>>filename;
	
	cout<<"Place input vocabulary:";
	cin>>pat.text;
	infile.open(filename);
	while(infile)
	{
		infile.getline(ob.text,MaxStrSize);
		k=0;
		while(k<ob.Getlength()-1)
		{
			j=KMP_find(ob,pat,k);
			if(j<0) break;
			else
			{
				i++;
				k=j+ob.Getlength();
			}
		}
		
	}
	infile.close();
	cout<<pat.text<<endl;
	cout<<"在文本文件:"<<filename<<"   "<<"总共出现"<<i<<"次"<<endl;
}

4.检索单词功能设计

void WordRetrieval()
{
	Word ob,pat;
	char filename[20];
	int i,j,k,l=0,m;
	int wz[20];
	ifstream infile;
	cout<<"Place text file name:";
	cin>>filename;
	cout<<"Place you need retrieval:";
	cin>>pat.text;
	infile.open(filename);
	while(infile)
	{
		infile.getline(ob.text,MaxStrSize);
		l++;k=0;i=0;
		while(k<ob.Getlength()-1)
		{
			j=KMP_find(ob,pat,k);
			if(j<0) break;
			else
			{
				i++;
				wz[i]=j;
				k=j+ob.Getlength();
			}
		}
		if(i>0)
		{
			cout<<"所在行:"<<l<<"    出现次数:"<<i;
			cout<<"在该行出现的位置分别是:";
			for(m=1;m<=i;m++) cout<<wz[m]+1;
			cout<<endl;
		}
	}
	infile.close();
	
}

关于界面设计的一些函数在这暂且不提,完整代码在文章末尾

2.实现界面:

《简单的利用c++实现 文本文件单词的检索和计数(KMP算法)》

 

附录 完整代码(文件下载在末尾)

#include<fstream>
#include<iostream>
#include<stdio.h>
#define MaxStrSize 100
using namespace std;

class Word
{
public:
	Word(){text[0]='\0';}
	int Getlength()const;
	void PlaceVocabulary();
	char text[MaxStrSize];
	
};

void GetFailure(const Word &pat,int f[])
{
	int j=0,k=-1;
	f[0]=-1;
	while(j<pat.Getlength()-1)
		if(k==-1||pat.text[k]==pat.text[j])
			f[++j]=++k;
		else
			k=f[k];
}

int KMP_find(Word ob,Word pat,int p=0)//p是用于下次匹配的开始检索位置
{
	int *f=new int[pat.Getlength()];
	GetFailure(pat,f);
	int i=p,j=0;
	while(i<ob.Getlength()&&j<pat.Getlength()&&pat.Getlength()-j<=ob.Getlength()-i)
	{
		if(j==-1||pat.text[j]==ob.text[i])
		{
			i++;
			j++;
		}
		else
			j=f[j];
	}
	delete []f;
	if(j<pat.Getlength())
		return -1;  
	else
		return i-j;
	
}
void WordCount()
{
	Word ob,pat;
	char filename[10];
	ifstream infile;
	int i=0,j,k;
	cout<<"Place input flie name:";
	cin>>filename;
	
	cout<<"Place input vocabulary:";
	cin>>pat.text;
	infile.open(filename);
	while(infile)
	{
		infile.getline(ob.text,MaxStrSize);
		k=0;
		while(k<ob.Getlength()-1)
		{
			j=KMP_find(ob,pat,k);
			if(j<0) break;
			else
			{
				i++;
				k=j+ob.Getlength();
			}
		}
		
	}
	infile.close();
	cout<<pat.text<<endl;
	cout<<"在文本文件:"<<filename<<"   "<<"总共出现"<<i<<"次"<<endl;
}
void WordRetrieval()
{
	Word ob,pat;
	char filename[20];
	int i,j,k,l=0,m;
	int wz[20];
	ifstream infile;
	cout<<"Place text file name:";
	cin>>filename;
	cout<<"Place you need retrieval:";
	cin>>pat.text;
	infile.open(filename);
	while(infile)
	{
		infile.getline(ob.text,MaxStrSize);
		l++;k=0;i=0;
		while(k<ob.Getlength()-1)
		{
			j=KMP_find(ob,pat,k);
			if(j<0) break;
			else
			{
				i++;
				wz[i]=j;
				k=j+ob.Getlength();
			}
		}
		if(i>0)
		{
			cout<<"所在行:"<<l<<"    出现次数:"<<i;
			cout<<"在该行出现的位置分别是:";
			for(m=1;m<=i;m++) cout<<wz[m]+1;
			cout<<endl;
		}
	}
	infile.close();
	
}
void Word::PlaceVocabulary()
{
	cout<<"Place input text:"<<endl;
	cin>>text;
}

int Word::Getlength() const
{
	int i;
	i=0;
	
	while(text[i]!='\0')
	{
		i++;
	}
	
	return i;
}

void Menu()
{
	cout<<"======================================="<<endl;
	cout<<"文本文件单词的检索和计数系统"<<endl;
	cout<<"======================================="<<endl;
	cout<<"1.建立文本文件"<<endl;
	cout<<"2.统计单词出现次数"<<endl;
	cout<<"3.检索单词"<<endl;
	cout<<"4.退出"<<endl;
	cout<<"请输入你的选择<1,2,3,4>:";
}
void CreateText()
{
	Word Text,end;
	char TextName[100];
	end.text[0]='/';
	end.text[1]='e';
	end.text[2]='n';
	end.text[3]='d';
	end.text[4]='\0';
	cout<<"请输入文件名:";
	cin>>TextName;
	ofstream outfile(TextName,ios::out);
	if(!outfile)
	{
		cerr<<"open error!"<<endl;
	}
	cout<<"请输入文本内容:(写完后用/end结束输入)"<<endl;

	while(KMP_find(Text,end)==-1)
	{
		cin>>Text.text;
		if(KMP_find(Text,end)==-1) 
			for(int i=0;i<Text.Getlength();i++) outfile<<Text.text[i];
			outfile<<'\n';
	}
	outfile.close();
	cout<<"Text create success"<<endl;
}
int main()
{
	
	int i,j=1;
	do{
		
		Menu();
		cin>>i;
		switch(i)
		{
		case 1:		CreateText();break;
		case 2:		WordCount();break;
		case 3:		WordRetrieval();break;
		case 4:		j=0;break;
		default:	cout<<"Place error"<<endl;
		}
		
	}while(j);	
	return 0;
}

下载地址:

https://download.csdn.net/download/keith_prime/10680681

    原文作者:KMP算法
    原文地址: https://blog.csdn.net/Keith_Prime/article/details/82797968
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞