LOADFACTOR/AddressList_Hash/AddList.cpp

444 lines
11 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <iostream>
#include "AddList.h"
#include "Hash.h"
#include "ArrayHash.h"
using namespace std;
typedef enum {Phone, Name} HashType;
HashType hash_type;
HashTable hash_table;
bool PutRecord(HashTable &hash_tabe, const char *key, AddList add, AddList &old_add, unsigned int (*Hash)(const char *key, int table_size) = ShiftHash) {
return Put(hash_tabe, key, add, old_add, Hash);
}
bool GetRecord(HashTable &hash_table, const char *key, AddList &add, unsigned int (*Hash)(const char *key, int table_size) = ShiftHash) {
return Get(hash_table, key, add, Hash);
}
bool RemoveRecord(HashTable &hash_table, const char *key, AddList &add, unsigned int (*Hash)(const char *key, int table_size) = ShiftHash) {
return Remove(hash_table, key, add, Hash);
}
void PrintLine() {
cout << "----------------------------------------------------" << endl;
}
void ClearTerminal() {
system("clear");
}
void PrintRecord(AddList add) {
cout << "---------------------------------------" << endl;
cout << "电话:" << add.phone_num << endl;
cout << "姓名:" << add.name << endl;
cout << "地址:" << add.address << endl;
cout << "---------------------------------------" << endl;
}
void AddRecordForm() {
ClearTerminal();
cout << "\n添加通讯录\n" << endl;
char phone_num[MAXPHONENUM];
char name[MAXNAME];
char address[MAXADDRESS];
char right[10];
cout << "\n电话号码:";
cin >> phone_num;
cout << "\n姓名:";
cin >> name;
cout << "\n通讯住址:";
cin >> address;
cout << "\n是否添加(Y 或 N)";
cin >> right;
if (right[0] == 'Y' || right[0] == 'y') {
AddList add(phone_num, name, address);
AddList old_add;
if (hash_type == Phone)
PutRecord(hash_table, add.phone_num, add, old_add);
else
PutRecord(hash_table, add.name, add, old_add);
cout << "\n已添加新记录:\n" << endl;
PrintRecord(add);
char continue_add[10];
cout << "\n是否继续添加(Y 或 N)";
cin >> continue_add;
if (continue_add[0] == 'Y' || continue_add[0] == 'y')
AddRecordForm();
else
MainForm();
} else
MainForm();
}
void QueryRecordForm() {
ClearTerminal();
cout << "\n查询通讯录\n" << endl;
cout << "1) 搜索电话\n" << endl;
cout << "2) 搜索姓名\n" << endl;
cout << "q) 返回\n" << endl;
cout << "\n> ";
char choose[10];
cin >> choose;
if (choose[0] == '1')
QueryRecordByPhoneNum();
else if (choose[0] == '2')
QueryRecordByName();
else
MainForm();
}
char g_phone[MAXNAME];
bool has_phone = false;
void TraverseFindPhone(AddList add) {
if (!strcmp(g_phone, add.phone_num)) {
PrintRecord(add);
has_phone = true;
}
}
void QueryRecordByPhoneNum() {
ClearTerminal();
cout << "\n输入电话号码查询记录\n" << endl;
char phone_num[MAXPHONENUM];
AddList add;
cout << "电话号码:";
cin >> phone_num;
if (hash_type == Phone) {
if (GetRecord(hash_table, phone_num, add)) {
cout << endl;
PrintRecord(add);
cout << endl;
} else {
cout << "\n该电话不存在\n" << endl;
}
} else {
strcpy(g_phone, phone_num);
TraverseHashTable(hash_table, TraverseFindPhone);
if (!has_phone)
cout << "\n该电话不存在\n" << endl;
}
char choose[10];
cout << "是否继续查询(Y 或 N)";
cin >> choose;
if (choose[0] == 'Y' || choose[0] == 'y')
QueryRecordByPhoneNum();
else
QueryRecordForm();
}
char g_name[MAXNAME];
bool has_name = false;
void TraverseFindName(AddList add) {
if (!strcmp(g_name, add.name)) {
PrintRecord(add);
has_name = true;
}
}
void QueryRecordByName()
{
ClearTerminal();
cout << "\n输入姓名查询记录\n" << endl;
char name[MAXPHONENUM];
AddList add;
cout << "姓名:";
cin >> name;
if (hash_type == Name) {
if (GetRecord(hash_table, name, add)) {
cout << endl;
PrintRecord(add);
cout << endl;
} else {
cout << "\n该姓名不存在\n" << endl;
}
} else {
strcpy(g_name, name);
TraverseHashTable(hash_table, TraverseFindName);
if (!has_name)
cout << "\n该姓名不存在\n" << endl;
}
char choose[10];
cout << "是否继续查询(Y 或 N)";
cin >> choose;
if (choose[0] == 'Y' || choose[0] == 'y')
QueryRecordByName();
else
QueryRecordForm();
}
void VisitRecord(AddList add) {
printf(" %-15s%-20s%-30s\n", add.phone_num, add.name, add.address);
}
void DisplayAllRecord() {
ClearTerminal();
PrintLine();
printf(" %-15s %-20s%-30s\n\n", "电话号码", "姓名", "通讯地址");
TraverseHashTable(hash_table, VisitRecord);
PrintLine();
cout << "\n\n按任意键返回..." << endl;
getchar();
getchar();
MainForm();
}
void ImportRecordsFromFile() {
ClearTerminal();
FILE* file = fopen("./records.txt", "r");
if (file) {
while (!feof(file)) {
AddList record, old_record;
fscanf(file, "%s%s%s", record.phone_num, record.name, record.address);
if (hash_type == Phone)
PutRecord(hash_table, record.phone_num, record, old_record);
else
PutRecord(hash_table, record.name, record, old_record);
}
cout << "\n导入成功" << endl;
fclose(file);
} else {
cout << "\n导入失败..." << endl;
}
cout << "\n\n按任意键返回..." << endl;
getchar();
getchar();
MainForm();
}
void GenerateRandomRecords(int total_num, AddList Records[]) {
const char char_set[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2',
'3', '4', '5', '6', '7', '8', '9', '\0'};
int char_set_len = strlen(char_set);
srand(time(NULL));
for (int i = 0; i < total_num; i++) {
char key[MAXKEYLEN] = {'\0'};
int len = rand() % MAX_RANDOM_STR_SIZE + 1;
for (int i = 0; i < len; i++) {
int ci = rand() % char_set_len;
key[i] = char_set[ci];
}
AddList add(key, key, key);
Records[i] = add;
}
}
void HashFuncCompare() {
ClearTerminal();
cout << "\n不同哈希函数性能对比\n" << endl;
int total_num;
double sum_asl = 0, shift_asl = 0, elf_asl = 0;
double sum_size = 0, shift_size = 0, elf_size = 0;
cout << "输入随机生成数据个数:";
cin >> total_num;
if (total_num <= 0)
total_num = 100;
AddList *Records = new AddList[total_num], old_add;
GenerateRandomRecords(total_num, Records);
HashTable sum_hash, shift_hash, elf_hash;
InitHashTable(sum_hash, 32);
InitHashTable(shift_hash, 32);
InitHashTable(elf_hash, 32);
for (int i = 0; i < total_num; i++) {
Put(sum_hash, Records[i].phone_num, Records[i], old_add, SumHash);
Put(shift_hash, Records[i].phone_num, Records[i], old_add, ShiftHash);
Put(elf_hash, Records[i].phone_num, Records[i], old_add, ELFHash);
}
sum_size = sum_hash.size;
shift_size = shift_hash.size;
elf_size = elf_hash.size;
sum_asl = GetASL(sum_hash, SumHash);
shift_asl = GetASL(shift_hash, ShiftHash);
elf_asl = GetASL(elf_hash, ELFHash);
DelHashTable(sum_hash);
DelHashTable(shift_hash);
DelHashTable(elf_hash);
cout << "\n统计结果:\n" << endl;
PrintLine();
printf("%10s\t%10s\t%10s\n", "Hash Fun", "Size", "ASL");
PrintLine();
printf("%10s\t%10.2f\t%10.2f\n", "SumHash", sum_size, sum_asl);
printf("%10s\t%10.2f\t%10.2f\n", "ShiftHash", shift_size, shift_asl);
printf("%10s\t%10.2f\t%10.2f\n", "ELFHash", elf_size, elf_asl);
PrintLine();
cout << "\n\n按任意键返回..." << endl;
getchar();
getchar();
MainForm();
}
void ConflictMethodCompare() {
ClearTerminal();
cout << "\n不同哈希函数性能对比\n" << endl;
int total_num;
double list_asl = 0, array_asl = 0;
double list_size = 0, array_size = 0;
cout << "输入随机生成数据个数:";
cin >> total_num;
if (total_num <= 0)
total_num = 100;
AddList *Records = new AddList[total_num], old_add;
GenerateRandomRecords(total_num, Records);
HashTable list_hash;
ArrayHashTable array_hash;
InitHashTable(list_hash, 32);
InitArrayHashTable(array_hash, total_num);
for (int i = 0; i < total_num; i++) {
Put(list_hash, Records[i].phone_num, Records[i], old_add, ShiftHash);
LinearPut(array_hash, Records[i].phone_num, Records[i], old_add);
}
list_size = list_hash.size;
array_size = array_hash.size;
list_asl = GetASL(list_hash, ShiftHash);
int sum = 0;
for (int i = 0; i < total_num; i++) {
int num;
AddList add;
LinearGetNum(array_hash, Records[i].phone_num, add, num);
sum += num;
}
array_asl = 1.0*sum / total_num;
DelHashTable(list_hash);
DelArrayHashTable(array_hash);
cout << "\n统计结果:\n" << endl;
PrintLine();
printf("%10s\t%10s\t%10s\n", "Conflict Method", "Size", "ASL");
PrintLine();
printf("%10s\t%10.2f\t%10.2f\n", "List Hash", list_size, list_asl);
printf("%10s\t%10.2f\t%10.2f\n", "Linear Hash", array_size, array_asl);
PrintLine();
cout << "\n\n按任意键返回..." << endl;
getchar();
getchar();
MainForm();
}
void MainForm() {
ClearTerminal();
PrintLine();
cout << "\n\n1) 添加通讯录\n" << endl;
cout << "2) 查询通讯录\n" << endl;
cout << "3) 查看全部通讯录\n" << endl;
cout << "4) 批量导入通讯录\n" << endl;
cout << "5) 不同哈希函数比较\n" << endl;
cout << "6) 不同冲突解决方法比较\n" << endl;
cout << "q) 退出\n\n" << endl;
PrintLine();
cout << "\n> ";
char op[10];
cin >> op;
if (op[0] == '1')
AddRecordForm();
else if (op[0] == '2')
QueryRecordForm();
else if (op[0] == '3')
DisplayAllRecord();
else if (op[0] == '4')
ImportRecordsFromFile();
else if (op[0] == '5')
HashFuncCompare();
else if (op[0] == '6')
ConflictMethodCompare();
else
return;
}
void ChooseHashType() {
ClearTerminal();
PrintLine();
cout << "\n\n选择建立哈希索引类型\n" << endl;
cout << "1) 以 电话号码 建立\n" << endl;
cout << "2) 以 姓名 建立\n" << endl;
cout << "q) 退出\n\n" << endl;
PrintLine();
cout << "\n> ";
char op[10];
cin >> op;
if (op[0] == '1')
hash_type = Phone;
else if (op[0] == '2')
hash_type = Name;
else
return;
InitHashTable(hash_table, 30);
MainForm();
}
void WelcomeForm() {
ClearTerminal();
PrintLine();
cout << "\n\n 哈希电话号码查找系统 \n\n";
cout << " 高天 \n\n";
cout << " 软件1601 \n\n";
cout << " 201616030213 \n\n";
PrintLine();
getchar();
ChooseHashType();
}
int main()
{
WelcomeForm();
return 0;
}