using namespace std;
#include <malloc.h>
#include <stdlib.h>
#include <string.h>
#include <iomanip>
#include <fstream>
#include <sstream>
#include <string>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
int a,b;
#define EQ(a,b) ((a)==(b))
#define LT(a,b) ((a) <(b))
#define LQ(a,b) ((a)> (b))
#define SUCCESS 1
#define UNSUCCESS 0
#define DUPLICATE -1
#define MAXSIZE 70 //哈希表的长度
#define NULLKEY -1 //空关键字的值
#define DELKEY -2 //被删关键字的值
typedef int KeyType;
typedef int Status;
typedef int ElemType;
typedef struct HASH{
KeyType key;
string ID;
string name;
string address;
struct HASH *next;
int count; //当前数据元素个数
//int sizeindex;
// hashsize[sizeindex]为当前容量
}HASH,*Hash, HashTable[MAXSIZE];
int HAsh(int key){
return key%47;
}
Status InsertHash(HashTable H,int &n,KeyType m,string ID,string na,string add,int p){
//把关键字K插入哈希表
int i,a;
a=HAsh(m);//MOD p取余数
Hash pre;
if(H[a].key==NULLKEY||H[a].key==DELKEY)
{
H[a].key=m;
H[a].ID=ID;
H[a].name=na;
H[a].address=add;
H[a].count=1;
}
else//冲突
{
cout<<" 1"<<endl;
Hash chain_adress;
chain_adress=(Hash)malloc(sizeof(HASH));
cout<<"4"<<endl;
chain_adress->key=m;
cout<<"4"<<endl;
//chain_adress->ID=ID;//此处出现错误
cout<<"4"<<endl;
chain_adress->name=na;
chain_adress->address=add;
cout<<"4"<<endl;
chain_adress->next=NULL;
cout<<"2 "<<endl;
pre = &H[a];
while (pre->next != NULL)
pre = pre->next;
cout<<"3"<<endl;
pre->next = chain_adress;
}
n++;
return OK;
}//InsertHash
template <class Type>
Type stringToNum(const string& str)
{
istringstream iss(str);
Type num;
iss >> num;
return num;
}
Status FileCreateHash(HashTable &H,int n,int m,int p){
//创建哈希表
int i,j,k,l=0;
KeyType id,sum=0;
char x[2];
string ID[70],na[70],add[70];
for(i=0;i<n;i++)
{
H[i].key=NULLKEY;
H[i].next=NULL;
}
fstream datafile;
datafile.open("IDcard.txt",ios::in);
if(!datafile)
{
cout<<"文件打开失败!"<<endl;
exit(ERROR);
}
for(i=0;i<m;i++)
{
H[i].key=NULLKEY;
//H[i].address=H[i].name=NULL;
H[i].count=0;
}
int *s;
for(i=0;i<n;i++)
{
sum=0;
datafile>>ID[i]>>na[i]>>add[i];
cout<<ID[i]<<na[i]<<add[i]<<endl;
for(k=0;k<=16;)
{
for(l=0;l<2;l++)
{
x[l]=ID[i][k];
k++;
}
id=atoi(x);
sum+=id;//关键字定义为十八位身份证号码每两位加在一起的和
cout<<id<<" "<<sum<<endl;
s[i]=sum;
}
cout<<(sum%47)<<endl;
InsertHash(H,j,sum,ID[i],na[i],add[i],p);
}
for(i=0;i<n;i++)
cout<<s[i]<<" ";
datafile.close();
return OK;
}//CreateHash
Status SearchHash(HashTable H,string ID)
{
//查找并显示给定身份信息的记录
int i,j,k,l,key;
char x[2];
int id,sum=0;
Hash h;
for(k=0;k<=16;)
{
for(l=0;l<2;l++)
{
x[l]=ID[k];
k++;
}
id=atoi(x);
sum+=id;
}
cout<<sum;
key=sum%47;
cout<<endl<<key<<endl;
for(i=0;i<MAXSIZE;i++)
{
if(key==H[i].key)
{
cout<<" "<<i<<endl;
if(ID==H[i].ID)
{
cout<<H[i].ID<<""<<H[i].name<<" "<<H[i].address<<endl;
cout<<1<<endl;
}
else
{
h=&H[i];
cout<<2<<endl;
while(ID!=h->ID)
{
h=h->next;
cout<<3;
}
cout<<h->ID<<" "<<h->name<<" "<<h->address<<endl;
}
break;
}
}
}
Status PrintHash(HashTable H,int n,int m){
//输出哈希表
int i;
float a=0;
cout<<"哈希表地址: ";
for(i=0;i<m;i++)
cout<<setw(6)<<i;//设置域宽为6个字符
cout<<endl<<"哈希表关键字为: ";
for(i=0;i<m;i++){
if(H[i].key==NULLKEY||H[i].key==DELKEY)
cout<<setw(6);
else
cout<<setw(6)<<H[i].key;
}
cout<<endl<<"搜索次数: ";
for(i=0;i<m;i++)
{
if(H[i].key==NULLKEY||H[i].key==DELKEY)
cout<<setw(6);
else
cout<<setw(6)<<H[i].count;
}
cout<<endl;
for(i=0;i<m;i++){
if(H[i].key!=NULLKEY||H[i].key!=DELKEY)
a=a+H[i].count;
}
a=a/n;
cout<<"平均搜索长度为:"<<a<<endl;
} //PrintHash
int main()
{
HashTable H;
cout<<"******哈希表演示*****"<<endl;
int n=47,m=13,p=47;
//int x[]={19,1,23,14,55,68,11,82,36};//示例数据用于测试
FileCreateHash(H,n,m,p);
cout<<endl;
cout<<"请输入要查找的身份证号码:"<<endl;
string ID;
cin>>ID;
SearchHash(H,ID);
//PrintHash(H,n,m);
return OK;
}
2 个解决方案
#1
崩溃的时候在弹出的对话框按相应按钮进入调试,按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处,
看不懂时双击下一行,直到能看懂为止。
#2
把InsertHash函数内的chain_adress = (Hash)malloc(sizeof(HASH));改成chain_adress = new HASH;试试
malloc只是分配堆内存(不会调用string的构造函数), 而new是分配且内存且在此创建一个对象(会调用构造函数)。
malloc只是分配堆内存(不会调用string的构造函数), 而new是分配且内存且在此创建一个对象(会调用构造函数)。
#1
崩溃的时候在弹出的对话框按相应按钮进入调试,按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处,
看不懂时双击下一行,直到能看懂为止。
#2
把InsertHash函数内的chain_adress = (Hash)malloc(sizeof(HASH));改成chain_adress = new HASH;试试
malloc只是分配堆内存(不会调用string的构造函数), 而new是分配且内存且在此创建一个对象(会调用构造函数)。
malloc只是分配堆内存(不会调用string的构造函数), 而new是分配且内存且在此创建一个对象(会调用构造函数)。