#include <iostream>
#include <set>
#include<fstream>
#include<cstring>
#include<stdlib.h>
using namespace std;
const int MAX_NOOD = 1e3;
const int CHARSET = 52;
class txtsearch
{
public:
txtsearch();
void trieinsert(string w,int txtnum);
int triesearch(string s);
void initial();
bool showtxt(int t);
void filltrie();
void findword(string word);
void ANDans(string ask[],int num);
void ORans(string ask[],int num);
public:
int trie[MAX_NOOD][CHARSET]; // trie[i][j] = x
set<int> txttag[MAX_NOOD];
int k;
string txt[21][10000];
int txtsize[21];
};
void txtsearch::ORans(string ask[],int num)
{
int txttmp[21];
memset(txttmp,0,sizeof(txttmp));
for(int i = 0;i<num;i++)
{
int o = triesearch(ask[i]);
if(o!=-1&&!txttag[o].empty())
{
for(set<int >::iterator it = txttag[o].begin();it!=txttag[o].end();it++)
txttmp[*it]++;
}
}
bool flag = false;
for(int i = 0;i<21;i++)
{
if(txttmp[i]!=0)
{
cout<<i<<".txt"<<" ";
flag = true;
}
}
cout<<endl;
if(flag) return;
else cout<<"Not Exists"<<endl;
}
void txtsearch::ANDans(string ask[],int num)
{
int txttmp[21];
memset(txttmp,0,sizeof(txttmp));
for(int i = 0;i<num;i++)
{
int o = triesearch(ask[i]);
if(o==-1||txttag[o].empty())
{
cout<<"Not Exists!"<<endl;
return;
}
else
{
for(set<int >::iterator it = txttag[o].begin();it!=txttag[o].end();it++)
txttmp[*it]++;
}
}
bool flag = false;
for(int i = 0;i<21;i++)
{
if(txttmp[i]==num)
{
cout<<i<<".txt"<<" ";
flag = true;
}
}
cout<<endl;
if(flag) return;
else cout<<"Not Exists"<<endl;
}
void txtsearch::findword(string word)
{
int o = triesearch(word);
if(o==-1||txttag[o].empty())
cout<<"Not Exists!"<<endl;
else
{
for(set<int >::iterator it = txttag[o].begin();it!=txttag[o].end();it++)
cout<<*it<<".txt"<<" ";
cout<<endl;
}
}
void txtsearch::filltrie()
{
for(int i=1;i<21;i++)
for(int j=0;j<txtsize[i];j++)
{
string ss;
if(txt[i][j][txt[i][j].size()-1]==','||txt[i][j][txt[i][j].size()-1]=='.')
ss = txt[i][j].substr(0,txt[i][j].size() - 1);
else
{
ss = txt[i][j];
}
trieinsert(ss,i);
}
}
void txtsearch::initial()
{
fstream f;
for(int i=1;i<21;i++)
{
char data_name[20];
sprintf(data_name, "%d%s",i, ".txt");
f.open(data_name,ios::in);
for(int k = 0;!f.eof();k++)
{
f>>txt[i][k];
txtsize[i]++;
}
f.close();
}
}
bool txtsearch::showtxt(int t)
{
bool flag = false;
for(int i = 0;i<txtsize[t];i++)
{
cout<<txt[t][i]<<" ";
flag = true;
}
cout<<endl;
return flag;
}
txtsearch::txtsearch()
{
//cout<<"nihao"<<endl;
memset(txtsize,0,sizeof(txtsize));
for(int i = 0;i<MAX_NOOD;i++)
for(int j = 0;j<CHARSET;j++)
trie[i][j] = 0;
for(int i = 0;i<MAX_NOOD;i++)
txttag[i].clear();
k = 1;
//cout<<"nihao";
}
void txtsearch::trieinsert(string w,int txtnum)
{
int len = w.length();
//cout<<len;
int p = 0;
for(int i = 0;i<len;i++)
{
int c;
if('a'<=w[i]&&w[i]<='z')
c = w[i] - 'a';
else if('A'<=w[i]&&w[i]<='Z')
c = w[i] - 'A'+26;
if(!trie[p][c])
{
trie[p][c] = k;
k++;
}
p = trie[p][c];
}
txttag[p].insert(txtnum);
}
int txtsearch::triesearch(string s)
{
int len = s.length();
int p = 0;
for(int i = 0;i<len;i++)
{
int c;
if('a'<=s[i]&&s[i]<='z')
c = s[i] - 'a';
else if('A'<=s[i]&&s[i]<='Z')
c = s[i] - 'A'+26;
if(!trie[p][c]) return -1;
p = trie[p][c];
}
return p;
}
int main()
{
string word,words[100];
int num;
txtsearch t;
cout<<"+--*--+--*--+--*--+--*--+--*--+--*--+--*--+--*--+--*--+--*--+--*--+--*--+--*--+--*--+"<<endl;
cout<<"| # # |"<<endl;
cout<<"| |"<<endl;
cout<<"| 欢迎你使用文本查询系统! |"<<endl;
cout<<"| |"<<endl;
cout<<"| # # |"<<endl;
cout<<"+--*--+--*--+--*--+--*--+--*--+--*--+--*--+--*--+--*--+--*--+--*--+--*--+--*--+--*--+"<<endl;
cout<<endl;
cout<<"已经为你在当前目录准备了1-20号txt文件,你现在可以对文本内容进行修改!"<<endl;
cout<<"准备好了吗?键入 OK 启动查询,键入 # 退出程序:"<<endl;
string s;
cin>>s;
if(s=="OK")
{
t.initial();
t.filltrie();
}
else exit(0);
cout<<"为你提供了如下功能:"<<endl;
cout<<"键入A 选择展示1-20号txt文件"<<endl;
cout<<"键入B 查找某个单词所在的txt文件"<<endl;
cout<<"键入C 查找多个单词同时出现的txt文件"<<endl;
cout<<"键入D 查找多个单词中至少出现一个的txt文件"<<endl;
cout<<"键入# 退出系统"<<endl;
char o;
while(cin>>o)
{
if(o=='#') exit(0);
else if(o=='A')
{
cout<<"请输入你要展示的文件编号(1-20):"<<endl;
int x;
cin>>x;
if(t.showtxt(x))
cout<<"END!"<<endl;
else
cout<<"Waring: Empty!"<<endl;
}
else if(o=='B')
{
cout<<"请输入你要查询的一个单词:"<<endl;
string w;
cin>>w;
t.findword(w);
}
else if(o=='C')
{
cout<<"请输入要查询的单词个数:"<<endl;
int n;
cin>>n;
cout<<"请以 word AND word 的形式输入这"<<n<<"个单词:"<<endl;
string ss[1000];
for(int i = 0;i<n;)
{
string s;
cin>>s;
if(s=="AND") continue;
else
{
ss[i] = s;
i++;
}
}
t.ANDans(ss,n);
}
else if(o=='D')
{
cout<<"请输入要查询的单词个数:"<<endl;
int n;
cin>>n;
cout<<"请以 word OR word 的形式输入这"<<n<<"个单词"<<endl;
string ss[1000];
for(int i = 0;i<n;)
{
string s;
cin>>s;
if(s=="OR") continue;
else
{
ss[i] = s;
i++;
}
}
t.ORans(ss,n);
}
}
//cout<<"nihao"<<endl;
// txtsearch test;
// test.trieinsert("in",1);
// test.trieinsert("inn",1);
// test.trieinsert("int",2);
// test.trieinsert("tea",2);
}
前缀树实现
最新推荐文章于 2024-11-04 21:43:20 发布