11-散列1 电话聊天狂人 (25 分)
给定大量手机用户通话记录,找出其中通话次数最多的聊天狂人。
输入格式:
输入首先给出正整数N(≤10
5
),为通话记录条数。随后N行,每行给出一条通话记录。简单起见,这里只列出拨出方和接收方的11位数字构成的手机号码,其中以空格分隔。
输出格式:
在一行中给出聊天狂人的手机号码及其通话次数,其间以空格分隔。如果这样的人不唯一,则输出狂人中最小的号码及其通话次数,并且附加给出并列狂人的人数。
输入样例:
4
13005711862 13588625832
13505711862 13088625832
13588625832 18087925832
15005713862 13588625832
输出样例:
13588625832 3
代码
#include <iostream>
#include<string>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<stdio.h>
#pragma warning(disable: 4996)
using namespace std;
#define MaxTelNum 11
#define MaxSize 200000
typedef char Elementype[MaxTelNum+1];
typedef struct ListNode* List;
typedef struct HashNode* HashTable;
typedef int Index;
typedef Index Position;
struct ListNode {
Elementype key;
int times;
List next;
ListNode() :times(0), next(NULL) {};
};
struct HashNode {
int Size;
List heads;
};
int NextPrime(int N) {
int res,i;
int IsPrime=1;
res = (N % 2) ? N + 2 : N + 1;
while (1) {
IsPrime = 1;
for (i = 2; i*i<=res; i++) {
if (res%i == 0) {
IsPrime = 0; break;
}
}
if (IsPrime == 1)
break;
else
res = res + 2;
}
return res;
}
Index Hash(Elementype key,HashTable H) {
int TableSize = H->Size;
Index pos = atoi(key + 6)%TableSize;
return pos;
}
List FindElement(Elementype key, HashTable H) {
Index Pos;
List tmp=NULL;
Pos = Hash(key, H);
tmp = H->heads[Pos].next;
while (tmp != NULL) {
if (strcmp(key, tmp->key) == 0) break;
else tmp = tmp->next;
}
return tmp;
}
void InsertHashTable(Elementype key, HashTable H) {
List PosToInsert, tmp;
Index Pos;
Pos = Hash(key, H);
PosToInsert = FindElement(key, H);
if (PosToInsert != NULL) {
PosToInsert->times++;
}
else {
PosToInsert = new ListNode;
PosToInsert->next = H->heads[Pos].next;
strcpy(PosToInsert->key, key);
PosToInsert->times = 1;
H->heads[Pos].next = PosToInsert;
}
}
HashTable BuildHashTable(HashTable H) {
int N;
Elementype tmp;
cin >> N;
int TableSize;
TableSize = NextPrime(2*N);
H->Size = TableSize;
H->heads = new ListNode[TableSize];
for (int i = 0; i < N; i++) {
cin >> tmp; InsertHashTable(tmp, H);
cin >> tmp; InsertHashTable(tmp, H);
}
return H;
}
void StaticHashTable(HashTable H) {
/*遍历hashtable中的最大的数,并记录下最大节点*/
List P;
List tmp=NULL;
int MaxTimes = 0;
int count = 1;
for (int i = 0; i < H->Size; i++) {
P = H->heads[i].next;/*从每一个的头结点开始*/
while (P != NULL) {
if (MaxTimes < P->times) {
MaxTimes = P->times;
tmp = P;
count = 1;
}
if(tmp!=P&&MaxTimes == P->times) {
tmp = strcmp(tmp->key, P->key) < 0 ? tmp : P;
count++;
}
P = P->next;
}
}
cout << tmp->key << " " << tmp->times;
if (count != 1) {
cout << " " << count;
}
}
int main() {
HashTable H= new HashNode;;/*没有经过初始化的指针没法传到函数中,因为函数不知道要复制什么*/
H=BuildHashTable(H);
StaticHashTable(H);
return 0;
}