#include<iostream>
#include<string>
#include<vector>
#include<fstream>
#include<sstream>
#include<set>
using namespace std;
/*unsigned int BKDRHash(const string str)
{
unsigned int seed=131;
unsigned int hash=0;
string::const_iterator it;
cout<<sizeof(unsigned int)<<endl;
for(it=str.begin();it!=str.end();it++)
{
hash=hash*seed+*it;
}
return hash & 0x7FFFFFFF;
}
*/
//c++关键字列表
const unsigned int M=66; //关键字个数
const string KeyList[M]={"asm","auto","bad_cast","const_cast","dynamic_cast","reinterpret_cast","static_cast",
"bad_typeid","bool","break","case","catch","throw","try","char","class","type","const","continue","delete",
"do","double","else","enum","explicit","export","extern","false","true","float","for","friend","goto","if"
,"inliine","int","long","mutable","namespace","new","operator","private","protected","public","register",
"return","short","signed","unsigned","static","struct","switch","template","typedef","typeid","typename",
"union","using","void","volatile","wchar_t","while","this","for","cout","cin"};
vector<string>kl(KeyList,KeyList+M);
typedef struct HashNode //哈希节点
{
string key;
struct HashNode *link;
};
const unsigned int N=26;
typedef HashNode *array[N]; //哈希数组
class HashofAlphabet
{
private:
array HashList;
unsigned int HashFuction(const string& str); //哈希函数
public:
HashofAlphabet();
HashNode* Locate(const string& str); //查找关键字
bool Insert(const string& str); //插入关键字
bool Create(const vector<string>& keylist); //创建Hash表
void show() const;
};
HashofAlphabet::HashofAlphabet()
{
int i;
for(i=0;i<N;i++)
{
this->HashList[i]=0; //初始化使得每个指针为空
}
}
bool HashofAlphabet::Create(const vector<string>& keylist)
{
vector<string>::const_iterator it;
for(it=keylist.begin();it!=keylist.end();it++)
{
if(!this->Insert(*it))
{
cerr<<"内存空间不足,插入失败!"<<endl;
return false;
}
}
return true;
}
unsigned int HashofAlphabet::HashFuction(const string& str)
{
return static_cast<int>(str[0]-'a');
}
HashNode* HashofAlphabet::Locate(const string& str)
{
unsigned int index=this->HashFuction(str);
if(index<0 || index>=N) return 0; // 下标超出合法范围
HashNode *p=this->HashList[index];
while(p)
{
if(p->key==str) return p;
p=p->link;
}
return 0;
}
bool HashofAlphabet::Insert(const string &str)
{
HashNode *p=new HashNode;
if(!p) return false;
p->key=str;
p->link=0;
unsigned int pos=this->HashFuction(str);
p->link=this->HashList[pos]; //采用前插
this->HashList[pos]=p;
return true;
}
void HashofAlphabet::show() const
{
int i;
HashNode *p;
for(i=0;i<N;i++)
{
cout<<"哈希值是"<<i<<"的有:";
for(p=this->HashList[i];p;p=p->link)
{
cout<<p->key<<" ";
}
cout<<endl;
}
}
class FileNotOpen //文件无法打开异常类
{
public:
string what()
{
string str="文件无法打开,没有此文件或目录!";
return str;
}
};
class Convert //转换类
{
private:
bool HasKuohao(const string& str); //判断字符串是不是含有括号
bool HasJianKuohao(const string& str); //判断字符串是不是含有尖括号
public:
void ReadFile(const string& filename,vector<string>& tmp);//将文件内容读入到向量tmp中
};
bool Convert::HasKuohao(const string& str)
{
string::const_iterator it;
for(it=str.begin();it!=str.end();it++)
{
if(*it=='(') return true;
}
return false;
}
bool Convert::HasJianKuohao(const string& str)
{
string::const_iterator it;
for(it=str.begin();it!=str.end();it++)
{
if(*it=='<') return true;
}
return false;
}
void Convert::ReadFile(const string& filename,vector<string>& tmp)
{
ifstream infile; //定义输入流文件
try
{
infile.open(filename.c_str(),ios::in); //以读方式打开此文件
if(!infile) throw FileNotOpen();
}
catch(FileNotOpen& e)
{
cerr<<e.what()<<endl;
exit(-1);
}
catch(...)
{
cerr<<"Something unexpected!"<<endl;
}
string s;
while(getline(infile,s)) //获取每一行
{
stringstream line(s); //初始化字符串流对象
string word;
while(line>>word)
{
if(!this->HasKuohao(word) && !this->HasJianKuohao(word)) tmp.push_back(word); //此单词不含有左括号
//也不含有<,括号直接放入向量tmp中
else if(this->HasKuohao(word))//含有左括号
{
string prekuohao=""; //括号前的内容
string::iterator it=word.begin();
while(*it!='(') prekuohao+=*it++;
tmp.push_back(prekuohao); //将左口号前的内容放入
tmp.push_back("(");
it++;
string betweenkuohao=""; //左右括号间的内容
while(it!=word.end() && *it!=')') betweenkuohao+=*it++;
if(betweenkuohao.empty()==false) //左右括号间的内容确实有内容
{
stringstream ss(betweenkuohao);
string word;
while(ss>>word)
{
tmp.push_back(word); //将左右括号间的内容放入
}
}
if(*it==')') tmp.push_back(")");
}
else //含有<括号
{
string prekuohao=""; //括号前的内容
string::iterator it=word.begin();
while(*it!='<') prekuohao+=*it++;
tmp.push_back(prekuohao); //将左口号前的内容放入
tmp.push_back("<");
it++;
string betweenkuohao=""; //左右括号间的内容
while(it!=word.end() && *it!='>') betweenkuohao+=*it++;
if(betweenkuohao.empty()==false) //左右括号间的内容确实有内容
{
stringstream ss(betweenkuohao);
string word;
while(ss>>word)
{
tmp.push_back(word); //将左右括号间的内容放入
}
}
if(*it=='>') tmp.push_back(">");
}
}
}
infile.clear(); //清除文件流
infile.close(); //关闭文件
}
class Print_FileContent //打印文件内容抽象类
{
protected:
vector<string>storevector; //存储文件内容的向量
Convert c;
string filename;
HashofAlphabet hash; //哈希对象
public:
virtual void print()=0;
};
class Print_Keyword:public Print_FileContent
{
private:
bool Occurance[M]; //表示关键字是不是已经出现过,在打印时去除重复的关键字
unsigned int PositionOfKl(const string& key); //关键字在kl向量中的位置
public:
Print_Keyword();
void print();
};
Print_Keyword::Print_Keyword()
{
hash.Create(kl); //创建Hash
int i;
for(i=0;i<M;i++) Occurance[i]=false; //表示第i个关键字没有出现过
}
unsigned int Print_Keyword::PositionOfKl(const string& key)
{
vector<string>::const_iterator it;
for(it=kl.begin();it!=kl.end();it++)
{
if(*it==key)
{
return it-kl.begin();
}
}
}
void Print_Keyword::print()
{
cout<<"请输入c++源文件完整路径(如c:\\study\ss\aa.cpp):";
cin>>filename;
c.ReadFile(filename,storevector);
vector<string>::const_iterator it;
cout<<"此源文件中C++的关键字是:"<<endl;
int pos; //关键字在Occurance中位置
for(it=storevector.begin();it!=storevector.end();it++)
{
if(hash.Locate(*it)) //是关键字
{
pos=this->PositionOfKl(*it); //找到这个关键字的
if(!this->Occurance[pos])
{
cout<<*it<<endl;
this->Occurance[pos]=true;
}
}
}
}
class Print_FunctionName:public Print_FileContent //打印函数名类
{
private:
set<string>name; //存放已经打印的文件名
public:
Print_FunctionName();
void print();
};
Print_FunctionName::Print_FunctionName()
{
this->hash.Create(kl);
}
void Print_FunctionName::print()
{
cout<<"请输入c++源文件完整路径(如c:\\study\ss\aa.cpp):";
cin>>filename;
c.ReadFile(filename,storevector);
vector<string>::const_iterator it;
cout<<"此源文件中C++的函数是:"<<endl;
int pos; //关键字在Occurance中位置
for(it=storevector.begin();it!=storevector.end();it++)
{
if(*it=="(" && it>storevector.begin()) //左括号前可能是函数名
{
if(hash.Locate(*(it-1))) break; //左括号前是关键字
else
{
if(name.count(*(it-1))==0)
{
cout<<*(it-1)<<endl;
name.insert(*(it-1));
}
}
}
}
}
void main()
{
Print_Keyword pk;
pk.print();
Print_FunctionName pf;
pf.print();
}