5、Hash表应用(必做)(查找)
[问题描述]
设计散列表实现VIP客户发掘。对身份证号进行Hash, 通过对乘客某时间段内的乘机频率、里程数统计,发掘VIP客户。
[基本要求]
(1)设每个记录有下列数据项:身份证号码(虚构,位数和编码规则与真实一致即可)、姓名、航班号、航班日期、里程。
(2)从文件输入各记录,以身份证号码为关键字建立散列表。
(3)分别采用开放定址(自行选择和设计定址方案)和链地址两种方案解决冲突;显示发生冲突的次数、每次中解决冲突进行重定位的次数。
(4)记录条数至少在100条以上。
(5)从记录中实现乘客乘机频率、里程数统计,从而发掘VIP客户。
#include <iostream>
#include <fstream>
#include <map>
#include <set>
#include <queue>
#include <algorithm>
#include <sstream>
#include <time.h>
#include <math.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <windows.h>
#define OK 1
#define TRUE 1
#define FALSE 0
#define MAXSIZE 65536 //潜在VIP条件:
#define DIS 5000 //累计飞行距离达到5000
#define TIME 6 //累计飞行次数达到6
using namespace std;
typedef int status;
typedef int Status;
typedef int ElemType;
typedef string DataType;
struct Date{
int year;
int month;
int day;
};
struct Passenger{
string ID; //身份证
string name; //名字
string FlightID; //飞行航班
Date date; //飞行日期
ElemType distance; //距离
ElemType time = 1; //飞行时长
ElemType IsVIP = 0; //VIP? First is not
};
struct PassengerLink{ //乘客链表
string ID;
string name;
string FlightID;
Date date;
int distance;
PassengerLink* next = NULL;
};
struct Hash{
Passenger* person = NULL;
int conflictiontime = 0;
};
struct Hashmap_Link{
PassengerLink* person = NULL;
};
struct FindID2{
string ID;
};
void FindFindID(FindID2 F,const string& ID){
F.ID = ID;
}
/*
Status operator(FindID F,vector<Passenger>::value_type& Id){
if(Id.ID == F.ID)
return TRUE;
else
return FALSE;
}
*/
class FindID{
private:
string ID;
public:
FindID(const string& ID)
{
this->ID = ID;
}
bool operator()(vector<Passenger>::value_type& Id)
{
return Id.ID == this->ID;
}
};
Status CountLines(string filename){//count lines
ifstream ReadFile;
int n = 0;
string tmp;
ReadFile.open(filename.c_str());
if (ReadFile.fail())
{
return FALSE;
}
else
{
while (getline(ReadFile, tmp, '\n'))
{
n++;
}
ReadFile.close();
return n;
}
}
string ReadLine(string filename, int line){ //函数文件读行
int lines, i = 0;
string temp;
fstream file;
file.open(filename.c_str());
lines = CountLines(filename);
if (line <= 0){
return "Error!";
}
if (file.fail()){
return "Error!!";
}
if (line > lines){
return "Error!!!";
}
while (getline(file, temp) && i < line - 1){
i++;
}
file.close();
return temp;
}
//void ReadFile(Passenger passenger){
void ReadFile(vector<Passenger>& passenger){
fstream file;
vector<Passenger>::iterator iter;
const char* fileName = "text5.txt";
file.open(fileName, ios::in);
if (file.fail()){
cout << "Open False" << endl;
exit(1);
}
int count = 0;
while (!file.eof()){
Passenger p;
file >> p.ID;
file >> p.name;
file >> p.FlightID;
file >> p.date.year;
file >> p.date.month;
file >> p.date.day;
file >> p.distance;
if (file.eof()){
break;
}
iter = find_if(passenger.begin(), passenger.end(), FindID(p.ID));
if (iter == passenger.end()){
passenger.push_back(p);
}
else
{
iter->time++;
iter->distance += p.distance;
}
}
}
void Createmap(Hash map[MAXSIZE],vector<Passenger>& passenger){//开放定址法
int count = 0;
string temp;
for (int i = 0; i < passenger.size(); i++){
//temp 作 哈希数
temp += passenger[i].ID[5]; //出生地第六位
temp += passenger[i].ID[8]; //出生年XX_X
temp += passenger[i].ID[9]; //出生年XXX_
temp += passenger[i].ID[17]; //尾号
stringstream ss; //string -> int
ss << temp;
int t ;
ss >> t;
if (map[t].person == NULL){
map[t].person = &passenger[i];
}
else{
int serial = t;
while (map[serial].person != NULL)
{
serial++;
count++;
}
map[serial].person = &passenger[i];
map[serial].conflictiontime = serial - t;
}
temp = "";
}
cout << "Clash:"<< count << endl;
}
void CreateLinkmap(Hashmap_Link map[MAXSIZE], vector<PassengerLink>& passenger){
int count = 0;
string temp;
for (int i = 0; i < passenger.size(); i++){
temp += passenger[i].ID[5];
temp += passenger[i].ID[8];
temp += passenger[i].ID[9];
temp += passenger[i].ID[17];
stringstream ss;
ss << temp;
int t ;
ss >> t;
cout << t <<" ";
if (map[t].person == NULL){
map[t].person = &passenger[i];
}
else{
PassengerLink* p = map[t].person;
while (p->next != NULL){
count++;
p = p->next;
}
PassengerLink* q = new PassengerLink;
q = &passenger[i];
q->next = NULL;
p->next = q;
count++;
}
temp = "";
}
cout << "Clash:" << count << endl;
}
int main()
{
// Passenger passenger;
vector<Passenger> passenger;
vector<PassengerLink> passengerlink;
ReadFile(passenger);
for (int i = 0; i < passenger.size(); i++){
PassengerLink p;
p.name = passenger[i].name;
p.ID = passenger[i].ID;
p.FlightID = passenger[i].FlightID;
p.date = passenger[i].date;
p.distance = passenger[i].distance;
p.next = NULL;
passengerlink.push_back(p);
}
for (int i = 0; i < passenger.size(); i++){
cout << passenger[i].ID;
cout << " ";
cout << passenger[i].name;
cout << " ";
cout << passenger[i].FlightID<<endl;
}
for (int i = 0; i < passenger.size(); i++){
if ((passenger[i].distance > DIS) || (passenger[i].time >= TIME)){
passenger[i].IsVIP = TRUE;
}
}
Hash map[MAXSIZE];
Createmap(map, passenger);
Hashmap_Link map_link[MAXSIZE];
cout << "Sum passengers:"<<passengerlink.size() << endl;
CreateLinkmap(map_link, passengerlink);
cout << "Maybe VIP:"<<endl;
for (int i = 0; i < passenger.size(); i++){
if (passenger[i].IsVIP == TRUE){
cout<< "* " << passenger[i].name << " : ";
cout<< "Fly times:" << passenger[i].time << " , ";
cout<< "Sum distance:" << passenger[i].distance << endl;
}
}
return 0;
}