📄 assistant.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 + -