7-20 电话聊天狂人(25 分)
给定大量手机用户通话记录,找出其中通话次数最多的聊天狂人。
输入格式:
输入首先给出正整数N(≤105),为通话记录条数。随后N行,每行给出一条通话记录。简单起见,这里只列出拨出方和接收方的11位数字构成的手机号码,其中以空格分隔。
输出格式:
在一行中给出聊天狂人的手机号码及其通话次数,其间以空格分隔。如果这样的人不唯一,则输出狂人中最小的号码及其通话次数,并且附加给出并列狂人的人数。
输入样例:
4
13005711862 13588625832
13505711862 13088625832
13588625832 18087925832
15005713862 13588625832
输出样例:
13588625832 3 code:
#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; }