给定大量手机用户通话记录,找出其中通话次数最多的聊天狂人。
输入格式:
输入首先给出正整数N(≤105),为通话记录条数。随后N行,每行给出一条通话记录。简单起见,这里只列出拨出方和接收方的11位数字构成的手机号码,其中以空格分隔。
输出格式:
在一行中给出聊天狂人的手机号码及其通话次数,其间以空格分隔。如果这样的人不唯一,则输出狂人中最小的号码及其通话次数,并且附加给出并列狂人的人数。
输入样例:
4
13005711862 13588625832
13505711862 13088625832
13588625832 18087925832
15005713862 13588625832
输出样例:
13588625832 3
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct LNode{
char PhoneNum[13];
int cnt;
struct LNode* Next;
};//储存每个电话号码的结构体
typedef struct LNode* Position;
typedef struct LNode* List;
struct HTable{
int Size;
List* TheList;//指针数组
};
typedef struct HTable* HashTable;
int prime[1000000];
void is_Prime(){
int i,j;
for(i = 0; i < 1000000; i++)
prime[i] = 1;
prime[0] = prime[1] = 0;
for(i = 2; i < 1000000; i++){
if(prime[i]){
for(j = i+i; j < 1000000; j += i)
prime[j] = 0;
}
}
}
int NextPrime(int n){
if(!prime[n]){
int i = n+1;
while(!prime[i])
i++;
return i;
}
else return n;
}//确定哈希表的大小是素数
HashTable Creat(int Size){
HashTable H;
H = (HashTable)malloc(sizeof(struct HTable));
H->Size = NextPrime(Size);
H->TheList = (List*)malloc(sizeof(List)*H->Size);//注意这里sizeof的是List指针形,因为这是个指针数组,每个单元是一个指针
int i;
for(i = 0; i < H->Size; i++){
H->TheList[i] = (List)malloc(sizeof(struct LNode));//这里sizeof的是结构体指针指向结构体
H->TheList[i]->Next = NULL;
}
return H;
}
void Destory(HashTable H){
int i;
for(i = 0; i < H->Size; i++)
free(H->TheList[i]);
free(H->TheList);
free(H);
}//释放空间
int Hash(int key,int Size){//哈希函数
return (key % Size);
}
Position Find(char key[],HashTable H){
Position P;
List L = H->TheList[Hash(atoi(key+6),H->Size)];//找到这个电话所分配的位置
//查找这个位置的链表中是否有这个电话号码
P = L->Next;
while(P && strcmp(key,P->PhoneNum)){
P = P->Next;
}
return P;//返回空或者相应的地址
}
void Insert(char key[],HashTable H){
Position pos,tmp;
List L = H->TheList[Hash(atoi(key+6),H->Size)];//确定位置
pos = Find(key,H);//看这个号码是否存在了
if(!pos){//不存在插入这个位置的链表
tmp = (List)malloc(sizeof(struct LNode));
strcpy(tmp->PhoneNum,key);
tmp->cnt = 1;
tmp->Next = L->Next;
L->Next = tmp;
}
else{
pos->cnt++;
}
}
void FindMax(HashTable H){
Position P;
int maxcnt = 0,maxsame = 1;
char minphone[13];
int i;
for(i = 0; i < H->Size; i++){//遍历每个位置的链表,类似邻接表
P = H->TheList[i]->Next;
while(P){
if(P->cnt > maxcnt){
maxcnt = P->cnt;
strcpy(minphone,P->PhoneNum);
maxsame = 1;
}
else if(P->cnt == maxcnt){
if(strcmp(minphone,P->PhoneNum) > 0){
strcpy(minphone,P->PhoneNum);
}
maxsame++;
}
P = P->Next;
}
}
printf("%s %d",minphone,maxcnt);
if(maxsame > 1)printf(" %d\n",maxsame);
}
int main(){
is_Prime();
int n;
int i;
char s1[13],s2[13];
scanf("%d",&n);
HashTable H = Creat(n*2);
for(i = 0; i < n; i++){
scanf("%s%s",s1,s2);
Insert(s1,H);
Insert(s2,H);
}
FindMax(H);
Destory(H);
return 0;
}