您的位置:首页 > 编程语言 > C语言/C++

哈希查找的应用之打印c++源文件中关键字和函数名

2012-05-26 21:26 281 查看
#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
; //哈希数组

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();

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息