⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 assistant.cpp

📁 文学助手的课程设计 文学研究人员需要统计某篇英文小说中某些形容词的出现次数和位置。试写一个实现这一目标的文字统计系统
💻 CPP
字号:
//assistant.cpp
#include<iostream>
#include<fstream>
#include<string>
using namespace std;

/**
*	相关宏定义
*/
#define MAX_WORD_LENGTH 1000		//最大字符串长度
#define MAX_MODELEXCEPTION_LENGTH 50
#define FILE_NAME_LENGTH 100		//文件名长度


/****************相关数据结构定义**************/

/**
*	从文件读取的字符串集合
*/
typedef struct FileString{
	string name;			//字符串名称
	int row;				//字符串所在的行
	FileString * next;		//邻接字符串
}FileString,*FSList;

/**
*	从键盘读取的字符串集合
*/
typedef struct KeyString{
	string name;			//字符串名称
	int * rows;				//字符串所在行向量
	int count;				//字符串出现的次数
	KeyString * next;		//邻接字符串
}KeyString,*KSList;

/**
*	匹配文本字符串和键盘字符串的模式匹配排除符集合
*/
typedef char * Model;

/**********************************************/

/****************数据操作声明******************/
int createFileString(FSList & FSL);
int insertFileString(FSList & FSL,string str,int row);
int getFSLength(FSList FSL);
int printFileString(FSList FSL);
int readFile(FSList & FSL);
int clearFileString(FSList & FSL);
int createKeyString(KSList & KSL);
int insertKeyString(KSList & KSL,string str);
int getKSLength(KSList KSL);
int printKeyString(KSList KSL);
int readKey(KSList & KSL);
int clearKeyString(KSList & KSL);

int count(string S,const string T,Model model);
void locate(FSList & FSL,KSList & KSL,Model model);

void ManualTip();
void LoginPaint();
int getModelException(Model & model);
int clearModelException(Model & model);
bool modelMatch(string s,Model model,int pos);

/**********************************************/

/****************测试代码********************/
int main(){
	ManualTip();	
	LoginPaint();
	int on;		//反复测试的标志
	do{	
		FSList FSL = NULL;
		KSList KSL = NULL;
		Model model = NULL;
		if(readFile(FSL)&&readKey(KSL)&&getModelException(model)){	//三串同时满足才开始查找
			char print = 'n';
			cout<<"Press 'y' to print the file\n";
			cin>>print;
			if(print=='y'){
				printFileString(FSL);
				cout<<"\n";
			}
			locate(FSL,KSL,model);
			printKeyString(KSL);
			clearKeyString(KSL);
			clearModelException(model);
			clearFileString(FSL);
		}
		cout<<"Press 1 to continue ....."<<endl;
		cin>>on;
		cin.ignore();
	}while(on == 1);
	return 0;
}
/*******************************************/

/****************数据操作实现******************/

/**
*	创建文件字符串集合
*/
int createFileString(FSList & FSL){		//创建字符串链表的表头
	FSL = new FileString;
	if(!FSL){
		cout<<"over flow"<<endl;
		exit(-1);
	}
	FSL->next = NULL;
	return 1;
}

/**
*	在文件字符串集合中插入新的字符串
*/
int insertFileString(FSList & FSL,string str,int row){
	if(!FSL)						//如果是空表,则创建集合
		createFileString(FSL);
	FSList sp ,tp;					
	sp = tp = FSL;
	while(sp = sp ->next)
		tp = sp;
	FSList s = new FileString;		//插在既有的集合中
	if(!s){
		cout<<"over flow!\n";
		exit(-1);
	}
	s->name = str;
	s->row = row;
	s->next = NULL;
	tp->next = s;					//顺序插入	
	return 1;
}

/**
*	求取文件字符串集合的长度
*/
int getFSLength(FSList FSL){
	int length = 0;
	if(!FSL){
		cout<<"Null character set"<<endl;
		return 0;
	}
	FSList sp = FSL;
	while(sp = sp->next){
		length++;
	}
	return length;
}

/**
*	打印文件字符串集合
*/
int printFileString(FSList FSL){
	if(!FSL){
		cout<<"Null character set\n";
		return 0;
	}
	FSList sp = FSL;
	while(sp = sp->next){
		cout<<sp->row<<" : "<<sp->name<<"\n";
	}
	return 1;
}

/**
*	从文件中读取串
*/
int readFile(FSList & FSL){
	char url[FILE_NAME_LENGTH];					//指向文件路径的const指针
	cout<<"Enter the file to read:";
	gets(url);
	while(url[0] == '\0'){						//保证文件名不为空
		cout<<"The file's name can not be null!"<<endl;
		gets(url);
	}
	ifstream fs = ifstream(url);				//打开文件读取字符串
	if(!fs){
		cout<<"File reads wrong!\n";
		return 0;
	}
	int rowLine = 1;
	string s;
	while(fs.peek()!=EOF){						//遇到文件尾符,结束读取
		getline(fs,s,'\n');						//依行读取s
		insertFileString(FSL,s,rowLine++);		//将获取的字符串插入文件字符串集合		
	}
	return 1;
}

/**
*	清空文件字符串集合
*/
int clearFileString(FSList & FSL){
	if(!FSL){
		return 1;
	}
	FSList p = FSL;
	while(p){						//释放字符串集合中的字符串节点	
		FSList q = p;
		p = p->next;
		delete q;
		q = NULL;
	}
	FSL = NULL;						//清空表头后赋NULL值
	return 1;
}


/**
*	创建键盘字符串集合
*/
int createKeyString(KSList & KSL){		//创建字符串链表的表头
	KSL = new KeyString;
	if(!KSL){
		cout<<"over flow"<<endl;
		exit(-1);
	}
	KSL->count = 0;
	KSL->rows = NULL;
	KSL->next = NULL;
	return 1;
}

/**
*	在键盘字符串集合中插入新的字符串
*/
int insertKeyString(KSList & KSL,string str){
	if(!KSL)							//如果是空表,则创建集合
		createKeyString(KSL);
	KSList sp ,tp;
	sp = tp = KSL;
	while(sp = sp ->next)
		tp = sp;
	KSList s = new KeyString;			//插在既有的集合中
	if(!s){
		cout<<"over flow!\n";
		exit(-1);
	}
	s->count = 0;
	s->name = str;
	s->rows = NULL;
	s->next = NULL;
	tp->next = s;						//顺序插入
	return 1;
}

/**
*	求取键盘字符串集合的长度
*/
int getKSLength(KSList KSL){
	int length = 0;
	if(!KSL){
		cout<<"Null character set!"<<endl;
		return 0;
	}
	KSList sp = KSL;
	while(sp = sp->next){
		length++;
	}
	return length;
}

/**
*	打印键盘字符串集合
*/
int printKeyString(KSList KSL){
	if(!KSL){
		cout<<"Null character set\n";
		return 0;
	}
	KSList sp = KSL;
	while(sp = sp->next){
		if(!sp->count)
			cout<<"\""<<sp->name<<"\" does not appeared in the file!\n";
		else{
			cout<<"\""<<sp->name<<"\" appeared "<<sp->count<<" times,at line ";
			int * rp = sp->rows;
			while(*rp){
				cout<<*rp<<" ";
				rp++;
			}
			cout<<endl;
		}
	}
	return 1;
}

/**
*	从键盘读取字符串集合
*/
int readKey(KSList & KSL){
	string s;
	cout<<"Enter the word to search(ended with space)"<<endl;
	while(1){
		getline(cin,s,' ');				//依行读取字符串
		insertKeyString(KSL,s);			//将获取的字符串插入字符串集合中
		if(cin.peek()=='\n')			//遇到行尾符,结束读取
			break;
	}
	return 1;
}

/**
*	清空键盘字符串集合
*/
int clearKeyString(KSList & KSL){
	if(!KSL){
		return 1;
	}
	KSList p = KSL;
	while(p){					//释放键盘字符串集合中字符串节点
		KSList q = p;
		p = p->next;
		delete q;
		q = NULL;
	}
	KSL = NULL;					//清空表头后赋NULL值
	return 1;
}

/**
*	查找模式串T在主串S中出现的次数
*/
int count(string S,const string T,Model model){
	int count = 0;	
	const char * tc = T.c_str();
	int i = 0;
	while(i < S.length()){
		//定义模式匹配规则----扫描排除字符
		if(modelMatch(S,model,i)){						//遇到模式匹配规则所定义的字符,则忽略读取
			i++;
			continue;
		}else{										//至此,S[i]肯定不是模式匹配的排除字符
			char * sc = new char[MAX_WORD_LENGTH];			
			char * sp = sc;
			//此处的while循环保证了在读取过程中始终保证不遇到模式匹配的排除字符
			while(S[i]!='\0'&&!modelMatch(S,model,i)){		//未至行尾并且没有遇到模式匹配规则所定义的排除字符,则读取
				*sp = S[i];			//读取子串
				sp++,i++;
			}
			*sp = '\0';	//结束子串读取
			if(!strcmp(sc,tc)){		//比较模式串和子串
				count++;			//相等则增加计数
			}
			delete sc;
		}
	}
	return count;
}

/**
*	定位KSL中字符串在FSL中的位置
*/
void locate(FSList & FSL,KSList & KSL,Model model){
	if(!FSL&&!KSL){
		cout<<"Null character set\n";
		return ;
	}
	KSList kp = KSL;				
	int i = 1;
	while(kp = kp->next){
		FSList fp = FSL;
		int * row = new int[getFSLength(FSL)+1];//对于键盘字符串集合中的每个字符串,row都会重新申请空间
		int * r = row;
		kp->rows = row;
		while(fp = fp->next){
			int c = count(fp->name,kp->name,model);
			if(c){				//kp->name在fp->name出现了,则统计其位置
				kp->count += c;
				*r = fp->row;
				r++;
			}
		}
		*r = 0;//堆栈指针指向空间最后单元的下个单元赋NULL值
	}
}

/*********************************************/

/*****************扩展代码********************/

/**
*	欢迎界面
*/
void LoginPaint(){
	ifstream in("welcome.txt");
	while(in.peek()!=EOF){
		string s;
		getline(in,s,'\n');
		cout<<s<<"\n";
	}
}

/**
*	手册提示
*/
void ManualTip(){
	LoginPaint();
	ifstream in("manual.txt");
	while(in.peek()!=EOF){
		string s;
		getline(in,s,'\n');
		cout<<s<<"\n";
	}
	cout<<"Enter any key to execute the application....\n";		//IO阻塞
	getchar();
	system("cls");			//清屏
}

/**
*	统计模式匹配排除字符
*/
int getModelException(Model & model){
	model = new char[MAX_MODELEXCEPTION_LENGTH];		//集合model能统计除了默认匹配字符外的所有客户指定的排除字符
	char match;
	cout<<"Press 'y' to add the Model-Exception-Character-Set\n";
	cin>>match;
	cin.ignore();					//避免其他方法的流操作带来负面影响
	int i = 0;
	while(match == 'y'){
		if(!i){
			cout<<"Begin to receive:";
		}
		if(cin.peek()=='\n'){
			if(!i){
				cout<<"No character received"<<endl;
			}
			cout<<"End receiving"<<endl;
			break;
		}
		cin.get(model[i++]);
	}
	//默认模式匹配排除符
	model[i] = ' ';	model[i+1] = ',';	model[i+2] = '.';	model[i+3] = '\'';	model[i+4] = '\"';
	model[i+5] = '\"';	model[i+6] = '*';	model[i+7] = '#';	model[i+8] = '!';	model[i+9] = '$';
	model[i+10] = '%';	model[i+11] = '^';	model[i+12] = '&';	model[i+13] = '(';	model[i+14] = ')';
	model[i+15] = '-';	model[i+16] = '+';	model[i+17] = '_';	model[i+18] = '|';	model[i+19] = '\\';
	model[i+20] = '{';	model[i+21] = '}';	model[i+22] = '[';	model[i+23] = ']';	model[i+24] = ':';
	model[i+25] = ';';	model[i+26] = '<';	model[i+27] = '>';	model[i+28] = '?';	model[i+29] = '/';
	model[i+30] = '~';	model[i+31] = '\t';	model[i+32] = '\0';				//串尾标志
	return 1;
}

/**
*	清空模式集合
*/
int clearModelException(Model & model){
	if(!model){
		return 1;
	}	
	delete model;
	return 1;
}

/**
*	模式匹配方法
*/
bool modelMatch(string s,Model model,int pos){
	for(int i = strlen(model) -1 ;i>=0;i--){
		if(s[pos] == model[i])		
			return true;			//字符和任一模式匹配排除符匹配,则表明该字符为排除符
	}
	return false;
}
/********************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -