给定大量手机用户通话记录,找出其中通话次数最多的聊天狂人。
输入格式:
输入首先给出正整数N(≤10^5 ),为通话记录条数。随后N行,每行给出一条通话记录。简单起见,这里只列出拨出方和接收方的11位数字构成的手机号码,其中以空格分隔。
输出格式:
在一行中给出聊天狂人的手机号码及其通话次数,其间以空格分隔。如果这样的人不唯一,则输出狂人中最小的……号码及其通话次数,并且附加给出并列狂人的人数。
输入样例:
4
13005711862 13588625832
13505711862 13088625832
13588625832 18087925832
15005713862 13588625832
输出样例:
13588625832 3
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
typedef struct HashList* List;
struct HashList{
char num[12];
int count;
List Next;
};
typedef struct HashTbl *Hashtable;
struct HashTbl{
int Tablesize;
List Cell;
};
int Hash(int Key,int p){
return Key%p;
}
int Nextprime(int n){
int i;
if(n%2==0)n++;
while(1)
{
int f=1;
for(i=2;i<sqrt(n);i++)
{
if(n%i==0)
{
f=0;break;
}
}
if(f){
return n;
}else{
n+=2;
}
}
}
Hashtable Create(int n)
{
Hashtable p=(Hashtable)malloc(sizeof(struct HashTbl));
p->Tablesize=Nextprime(n);
p->Cell=(List)malloc(sizeof(struct HashList)*(p->Tablesize));
int i;
for(i=0;i<p->Tablesize;i++){
p->Cell[i].count=0;
p->Cell[i].Next=NULL;
p->Cell[i].num[0]='\0';
}
return p;
}
void Insert(Hashtable H,char *s){
/*注意,这里的哈希元素结点链表是带头指针的*/
List pf=&(H->Cell[Hash(atoi(s+6),H->Tablesize)]);
/*pf为头结点*/
List p=pf->Next;
int i=0;
if(p)i=1;
while(p){
if(!strcmp(p->num,s)){
p->count++;
break;
}else{
p=p->Next;
}
}
/*跳出循环的时候p为NULL,说明要把s这个字符插入,即这个地址有新的电话号码*/
if(!p)
{
List t=(List)malloc(sizeof(struct HashList));
t->Next=pf->Next;
t->count=1;
strcpy(t->num,s);
pf->Next=t;
}
}
void Output(Hashtable H){
int i;int number=0;
char Minnum[12];
Minnum[0]='\0';
int Max=0;
for(i=0;i<H->Tablesize;i++){
List P=H->Cell[i].Next;
while(P)
{
if(P->count>Max){
number=1;
Max=P->count;
strcpy(Minnum,P->num);
}else if(P->count==Max){
number++;
if(strcmp(Minnum,P->num)>0)
strcpy(Minnum,P->num);
}
P=P->Next;
}
}
printf("%s %d",Minnum,Max);
if(number>1)
printf(" %d",number);
printf("\n");
}
int main(){
int n;scanf("%d",&n);
Hashtable H=Create(n);
int j;char s[12];
for(j=0;j<2*n;j++){
scanf("%s",s);
Insert(H,s);
}
Output(H);
return 0;
}