11.散列1 电话聊天狂人 [分离链表法]
11-散列1 电话聊天狂人 (25分)
给定大量手机用户通话记录,找出其中通话次数最多的聊天狂人。
输入格式:
输入首先给出正整数N(≤10
5 ),为通话记录条数。随后N行,每行给出一条通话记录。简单起见,这里只列出拨出方和接收方的11位数字构成的手机号码,其中以空格分隔。
输出格式:
在一行中给出聊天狂人的手机号码及其通话次数,其间以空格分隔。如果这样的人不唯一,则输出狂人中最小的号码及其通话次数,并且附加给出并列狂人的人数。
输入样例:
4
13005711862 13588625832
13505711862 13088625832
13588625832 18087925832
15005713862 13588625832
输出样例:
13588625832 3
——————————————————————————————
#include<iostream> //用分离链表法
#include<string>
#include<stdio.h>
#include<cmath>
using namespace std;
#define max 10000000
struct node { //定义链表中的每个结点
string number;
node* next;
int count;
};
struct hashtable { //定义散列表结点
int tablesize;
node* heads; //头结点数组(每一行接一个链表)
};
//确定哈希表的表长(找大于个数的最小素数)
int hashsize(int n) {
int p=(n % 2)?n + 2: n + 1;
int i;
while (p <= max) { //在奇数里面找
for (i = (int)sqrt(p);i >2; i--)
if (!(p % i)) break;
if (i == 2)break;
else p += 2;
}
return p;
}
hashtable* create(int tablesize) { //创建哈希表
hashtable* h = new hashtable;
h->tablesize = hashsize(tablesize);
h->heads = new node[h->tablesize];
for (int i = 0; i < h->tablesize; i++) {
h->heads[i].next = NULL;
h->heads[i].count = 0;
}
return h;
}
int Hash(int key, int tablesize) { //确定映射机制
return key % tablesize;
}
node* find(hashtable* h, string key) {
int pos = Hash(atoi(key.substr(6, 5).c_str()), h->tablesize);
node* p = h->heads[pos].next;
while (p && key!=p->number) //string 类型直接比大小
p = p->next;
return p;
}
bool insert(hashtable* h, string key) {
node* p = find(h, key);
if (!p) { //如果原先没有p结点
node* tmp = new node;
tmp->number = key;
tmp->count = 1;
int pos = Hash(atoi(key.substr(6, 5).c_str()), h->tablesize);
tmp->next = h->heads[pos].next;
h->heads[pos].next = tmp;
return true;
}
//关键词已存在
else {
p->count++; //插入的时候就记数了
return false;
}
}
void scanandoutput(hashtable* h) {
node* p;
int maxcount = 0;//最大通话次数
string minnumber;//最小号码;
int pnt = 0;//并列人数
for (int i = 0; i < h->tablesize; i++) {
p = h->heads[i].next;
while (p) {
if (maxcount < p->count) {
maxcount = p->count;
minnumber = p->number;
pnt = 1;
}
else if (p->count == maxcount) {
if (p->number < minnumber)
minnumber = p->number;
pnt++;
}
p = p->next;
}
}
cout << minnumber << " " << maxcount;
if (1 < pnt)
cout << " " << pnt;
}
int main() {
hashtable* h;
int n;
string key;
cin >> n;
h = create(2 * n);
for (int i = 0; i < n; i++) {
cin >> key; insert(h, key);
cin >> key; insert(h, key);
}
scanandoutput(h);
return 0;
}