C++实现的哈希搜索
C++实现的哈希搜索
程序内容
Complete a text searching engine using hash table.
完成一个文本搜索引擎,使用哈希表
程序设计
程序流程图

程序代码
程序变量
const int HASH_SIZE=100;
vector<string> container;
struct hash_node{
int number;
string key;
hash_node* next;
hash_node(string a="",int b=0,hash_node* c=NULL);
};
hash_node* hash_chain=NULL;
string word;
初始化
方法是从文件流单个读取字符,遇到句号,问号,感叹号和省略号都视为断句标志,利用了char和string之间的转换,出现bug的情况是句子字符长度超过1024,这个概率太小。程序兼顾了去除前导空格的功能。
bool ReadFile(string source){//读取文件并存储
ifstream fin;
fin.open(source.c_str());
if(!fin){//打开文件失败
cout<<"Unable to open "<<source<<"."<<endl;
return false;
}
//cout<<"open success"<<endl;
container.clear();
char buffer[1024]={0};
int k=0;
string temp;
while(!fin.eof()){
buffer[k++]=fin.get();
//断句符有三个
if(buffer[k-1]=='.'||buffer[k-1]=='?'||buffer[k-1]=='!'){
temp=buffer;
container.push_back(temp);
memset(buffer,0,1024);
k=0;
while(!fin.eof()){
if(isalpha(buffer[k]=fin.get())){
k=1;
break;
}
}
}
}
fin.close();
cout<<"succeed to open "<<source<<"."<<endl;
return true;
}
创建哈希表
核心哈希函数,string转int,来源CSDN博客独孤小剑,自己改进了取模操作
int Hash(string &key){//哈希 string转int
int seed=31;
int hash=0;
int strln=key.length();
for(int i=0;i<strln;i++)
hash=(hash*seed+key[i])%HASH_SIZE;
return hash%HASH_SIZE;
}
生成哈希表函数,从容器中逐个取出单词(消除最后一个单词的标点符号),根据哈希函数存储在哈希表中,利用自定义的结构体。同一个句子中相同的单词只存储一次。
void CreatHashTable(){//生成哈希表
hash_chain=new hash_node [HASH_SIZE];
for(int i=0;i<HASH_SIZE;i++){//初始化
hash_chain[i].key="";
hash_chain[i].number=0;
hash_chain[i].next=NULL;
}
int pos;
string temp;
for(int i=0;i<container.size();i++){
temp=container[i];//去除结尾符号
transform(temp.begin(),temp.end(),temp.begin(),Cut);
//cout<<container[i]<<endl;
istringstream iss(temp);
while(iss>>temp){//读取单词
//cout<<temp<<endl;
pos=Hash(temp);
hash_node* p1=&hash_chain[pos];
if(p1->key==""){
p1->key=temp;
p1->number=i;
}
else{
bool repeat=false;
while(p1->next!=NULL){
if(temp==p1->key&&i==p1->number){
repeat=true;
break;
}
p1=p1->next;
}
if(temp==p1->key&&i==p1->number){
repeat=true;
}
if(repeat)
continue;
hash_node* pnew=new hash_node(temp,i,NULL);
pnew->next=p1->next;
p1->next=pnew;
}
}
}
}
搜索关键词
前提是成功打开文件。利用循环多次搜索,退出的关键词是END(大小写敏感)。instruction()函数中有说明退出方法。
int main()
{
instruction();
if(ReadFile("source.txt")){
//PrintContainer();
CreatHashTable();
cout<<"Please enter you key: ";
while((cin>>word)&&word!="END"){
SearchFor(word);
cout<<"Please enter you key: ";
}
DeleteHashTable();
}
return 0;
}
释放内存
良好习惯(强迫症罢了),据说这才是程序不崩溃的核心=。=
void DeleteHashTable(){//删除哈希表
hash_node *p1,*p2,*p3;
for(int i=0;i<HASH_SIZE;i++){
p1=&hash_chain[i];
p2=p1->next;
while(p2!=NULL){
p3=p2->next;
delete p2;
p2=p3;
}
}
delete [] hash_chain;
container.clear();
}
程序运行情况




完整代码
#include<bits/stdc++.h>
using namespace std;
const int HASH_SIZE=100;
vector<string> container;
struct hash_node{
int number;
string key;
hash_node* next;
hash_node(string a="",int b=0,hash_node* c=NULL);
};
hash_node* hash_chain=NULL;
string word;
bool ReadFile(string source);
void PrintContainer();
void CreatHashTable();
int Hash(string &key);
char Cut(char c);
void SearchFor(string word);
void instruction();
void DeleteHashTable();
int main()
{
instruction();
if(ReadFile("source.txt")){
//PrintContainer();
CreatHashTable();
cout<<"Please enter you key: ";
while((cin>>word)&&word!="END"){
SearchFor(word);
cout<<"Please enter you key: ";
}
DeleteHashTable();
}
return 0;
}
void instruction(){//程序介绍
cout<<"Programme: Search.cpp"<<endl;
cout<<"Author: Wsine"<<endl;
cout<<"Date: 2014-11-29"<<endl;
cout<<"Exit key is 'END'"<<endl<<endl;
}
bool ReadFile(string source){//读取文件并存储
ifstream fin;
fin.open(source.c_str());
if(!fin){//打开文件失败
cout<<"Unable to open "<<source<<"."<<endl;
return false;
}
//cout<<"open success"<<endl;
container.clear();
char buffer[1024]={0};
int k=0;
string temp;
while(!fin.eof()){
buffer[k++]=fin.get();
//断句符有三个
if(buffer[k-1]=='.'||buffer[k-1]=='?'||buffer[k-1]=='!'){
temp=buffer;
container.push_back(temp);
memset(buffer,0,1024);
k=0;
while(!fin.eof()){
if(isalpha(buffer[k]=fin.get())){
k=1;
break;
}
}
}
}
fin.close();
cout<<"succeed to open "<<source<<"."<<endl;
return true;
}
void PrintContainer(){//打印函数供测试使用
for(int i=0;i<container.size();i++)
cout<<container[i]<<endl;
}
int Hash(string &key){//哈希 string转int
int seed=31;
int hash=0;
int strln=key.length();
for(int i=0;i<strln;i++)
hash=(hash*seed+key[i])%HASH_SIZE;
return hash%HASH_SIZE;
}
char Cut(char c){//自定义切割函数
if(isalpha(c)||c=='\0')
return c;
else
return ' ';
}
void CreatHashTable(){//生成哈希表
hash_chain=new hash_node [HASH_SIZE];
for(int i=0;i<HASH_SIZE;i++){//初始化
hash_chain[i].key="";
hash_chain[i].number=0;
hash_chain[i].next=NULL;
}
int pos;
string temp;
for(int i=0;i<container.size();i++){
temp=container[i];//去除结尾符号
transform(temp.begin(),temp.end(),temp.begin(),Cut);
//cout<<container[i]<<endl;
istringstream iss(temp);
while(iss>>temp){//读取单词
//cout<<temp<<endl;
pos=Hash(temp);
hash_node* p1=&hash_chain[pos];
if(p1->key==""){
p1->key=temp;
p1->number=i;
}
else{
bool repeat=false;
while(p1->next!=NULL){
if(temp==p1->key&&i==p1->number){
repeat=true;
break;
}
p1=p1->next;
}
if(temp==p1->key&&i==p1->number){
repeat=true;
}
if(repeat)
continue;
hash_node* pnew=new hash_node(temp,i,NULL);
pnew->next=p1->next;
p1->next=pnew;
}
}
}
}
hash_node::hash_node(string a,int b,hash_node* c){//结构体构造函数
key=a;
number=b;
next=c;
}
void SearchFor(string word){//搜索函数
int pos=Hash(word),k=1;
hash_node* p1=&hash_chain[pos];
while(p1!=NULL){//遍历链表
if(p1->key==word){
cout<<endl;
cout<<"Sentence "<<k++<<" :"<<endl;
cout<<container[p1->number]<<endl;
}
p1=p1->next;
}
cout<<endl;
}
void DeleteHashTable(){//删除哈希表
hash_node *p1,*p2,*p3;
for(int i=0;i<HASH_SIZE;i++){
p1=&hash_chain[i];
p2=p1->next;
while(p2!=NULL){
p3=p2->next;
delete p2;
p2=p3;
}
}
delete [] hash_chain;
container.clear();
}
C++实现的哈希搜索的更多相关文章
- 如何在CentOS 7上安装Percona服务器
在这篇文章中我们将了解关于 Percona 服务器,一个开源的MySQL,MariaDB的替代品.InnoDB的数据库引擎使得Percona 服务器非常有吸引力,如果你需要的高性能,高可靠性和高性价比 ...
- JVM剖析
JVM剖析 这篇文章详细解释了Java虚拟机的内部架构.以下这幅图展示了Java虚拟机里面的关键组件(是依据Java SE 7版本的Java虚拟机). 这些组件将在下面的两个章节一一展开.第一章节涵盖 ...
- 《Python学习手册》读书笔记
之前为了编写一个svm分词的程序而简单学了下Python,觉得Python很好用,想深入并系统学习一下,了解一些机制,因此开始阅读<Python学习手册(第三版)>.如果只是想快速入门,我 ...
- 显示引擎innodb状态详解
很多人让我来阐述一下 SHOW INNODB STATUS 的输出信息,了解SHOW INNODB STATUS都输出了几个什么信息,并且我们能够这些信息中获取什么资讯,得以提高MySQL性能. 首 ...
- 《Python学习手册》读书笔记【转载】
转载:http://www.cnblogs.com/wuyuegb2312/archive/2013/02/26/2910908.html 之前为了编写一个svm分词的程序而简单学了下Python,觉 ...
- Hash Tables
哈希表 红黑树实现的符号表可以保证对数级别的性能,但我们可以做得更好.哈希表实现的符号表提供了新的数据访问方式,插入和搜索操作可以在常数时间内完成(不支持和顺序有关的操作).所以,在很多情况下的简单符 ...
- Windows五种IO模型性能分析和Linux五种IO模型性能分析
Windows五种IO模型性能分析和Linux五种IO模型性能分析 http://blog.csdn.net/jay900323/article/details/18141217 http://blo ...
- 【比赛】NOIP2017 宝藏
这道题考试的时候就骗了部分分.其实一眼看过去,n范围12,就知道是状压,但是不知道怎么状压,想了5分钟想不出来就枪毙了状压,与AC再见了. 现在写的是状压搜索,其实算是哈希搜索,感觉状压DP理解不了啊 ...
- Python学习手冊笔记
之前为了编写一个svm分词的程序而简单学了下Python.认为Python非常好用.想深入并系统学习一下,了解一些机制,因此開始阅读<Python学习手冊(第三版)>. 假设仅仅是想高速入 ...
随机推荐
- zip的打包与解包和包下载
text文件压缩包解析与下载 //压缩包下载 private StreamedContent newsTemplate; //该方法是对压缩包进行下载 public StreamedCont ...
- 事件委托和this
JavaScript不仅门槛低,而且是一门有趣.功能强大和非常重要的语言.各行各业的人发现自己最混乱的选择是JavaSscript编程语言.由于有着各种各样的背景,所以不是每个人都对JavaScrip ...
- Android IOS WebRTC 音视频开发总结(二四)-- p2p调用堆栈
本文主要分析webrtc音视频点对点部分的代码结构,文章来自博客园RTC.Blacker,转载请说明出处. 前段时间在查一个偶尔断线的问题(这种问题最蛋疼,不好重现,只能凭经验去搞),所以理了下web ...
- 十一、Struts2封装请求参数的方式
十一.Struts2封装请求参数的方式 方式一.Action 本身作为model对象,通过成员setter封装(一个名字为params的拦截器干的) 注意:表单中的名称要和动作类中的名称一致(这是必须 ...
- slf4j+log4j配置
下载三个包: 三个包分别是:log4j的API包,slf4j的API包,slf4j对log4j的适配包. 选择使用slf4j一个重要的原因是支持占位符{},不用频繁操作字符串对象. 实现代码如下: i ...
- 搭建高性能计算环境(八)、应用软件的安装之gromacs
1,下载安装新版本的gcc(高版本的gcc只是推荐使用的,系统自带的gcc4.4照样能正常编译.运行) wget http://ftp.tsukuba.wide.ad.jp/software/gcc/ ...
- Web前端代码规范与页面布局
一. 规范目的: 为提高工作效率,便于后台人员添加功能及前端后期优化维护,输出高质量的文档,在网站建设中,使结构更加清晰,代码简明有序,有一个更好的前端架构,有利于SEO优化. 二. ...
- 关于ASP.net TextBox控件的失去焦点后触发其它事件
编写人:CC阿爸 2015-2-02 今天在这里,我想与大家一起分享如何处理的ASP.net TextBox控件的失去焦点后触发其它事件的问题,在此做个小结,以供参考.有兴趣的同学,可以一同探讨与学习 ...
- silverlight获取web的url参数
1.网址(如:http://localhost:8081/index.aspx?name=123) 2.获取name=123的信息 3.IDictionary<string,string> ...
- php怎么解析utf-8带BOM编码的json数据,php解析json数据返回NULL
今天遇到一个问题,json_decode解析json数据返回null,试了各种方法都不行,最后发现,原来是json文件编码的问题. 当json_decode解析utf-8带BOM格式的json数据时, ...