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;
}


posted @ 2020-05-12 15:06  _Hsiung  阅读(98)  评论(0编辑  收藏  举报