7-17 电话聊天狂人(25 分)
给定大量手机用户通话记录,找出其中通话次数最多的聊天狂人。
输入格式:
输入首先给出正整数N(≤105),为通话记录条数。随后N行,每行给出一条通话记录。简单起见,这里只列出拨出方和接收方的11位数字构成的手机号码,其中以空格分隔。
输出格式:
在一行中给出聊天狂人的手机号码及其通话次数,其间以空格分隔。如果这样的人不唯一,则输出狂人中最小的号码及其通话次数,并且附加给出并列狂人的人数。
输入样例:
4
13005711862 13588625832
13505711862 13088625832
13588625832 18087925832
15005713862 13588625832
输出样例:
13588625832 3
这次来数组实现,大体思路还是处理数据 然后插入。哈希 用来大数据处理真的不错。
/**根据同学的提醒 发现一个小BUG 在插入函数的 平方查找合适位置的那个地方,现在已修改**/
代码:
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <ctype.h>
#define MAX 400000 /** 定义 最大 数组 大小 **///(感觉没啥用 但是最好尽可能开大点,但是不要太大,不要超出系统可建造范围)
typedef struct Node *Hash; /**新的路程又开始了 这次准备用数组来做哈希 还有双向平方处理冲突**/
struct Node{
char phone[15];
int num;
};
int max(int x,int y)
{
if(x>y) return x;
else return y;
}
char* minstr(char *x,char *y)
{
if(strcmp(x,y)>0) return y;
else return x;
}
int nextprime(const int n)
{
int p =(n%2==1)? n+2:n+1; /**先找一个大于N的奇数**/
int i;
while(p<MAX)
{
for(i=(int)sqrt(p);i>=2;i--) /**然后再判断是不是素数**/
if(p%i==0) break;
if(i<2) return p; /**是 那就返回这个数**/
else p+=2;/**不是 那就下一个奇数**/
}
}
int deal(char *s,int p) /**然后把字符串映射成下标 (映射的方式很多很多,随便猜一个靠谱的就行了)**/
{
int index = (atoi(s+2))%p;
return index;
}
int insert(Hash h,int pos,char *s,int p,int Max) /**哈希查找的插入实现 ,分别是哈希数组,数组位置,身份证号,数组最大大小, MAX 看到代码最后就明白了**/
{
int i,posb=pos; /**备份pos值方便双向平方查找**/
for(i=1;;i++)
{
if(strcmp(h[pos].phone,"")==0) /**如果为pos的值空直接插入**/
{
strcpy(h[pos].phone,s);
h[pos].num++;
Max=max(Max,h[pos].num);
break;
}
else
{
if(strcmp(h[pos].phone,s)==0) /**不为空的话,就看看身份证号是不是想等**/
{
h[pos].num++;
Max=max(Max,h[pos].num);
break;
}
else
{ //原p%2==1
if(i%2==1) pos=(posb+(i*i))%p; /**不相等 就找下一个位置 ,分别向后找一次和往前找一次,如此循环**/
else
{ //原i*i
pos = posb-((i-1)*(i-1));
while(pos<0)
pos+=p;
}
}
}
}
return Max;
}
void initial(Hash h, int p) /**把哈希数组初始化 (初始化的动词英文忘记咋写了。。。。)**/
{
int i;
for(i=0;i<p;i++)
{
h[i].phone[0]='\0';
h[i].num=0;
}
}
int main(){
int Max=0;
int n; /**总数 N 然后就开始找 大于N的最小素数了**/
scanf("%d",&n); /**输出中把\n也输入进去 避免下面输入会出现奇葩的事情**/
int p = nextprime(2*n); /**突然想起来 每次输入的都是俩电话号码,所以 电话号码最大数是2*n**/
Hash h =(Hash)malloc(p*sizeof(struct Node));/**建立哈希数组**/
initial(h,p);
char phone[15];
char phone1[15];
while(n--)
{
/*for(int i=0;i<p;i++)
{
printf("->>>%s %d\n",h[i].phone,h[i].num);
}
printf("the max is %d\n",Max);*/
scanf("%s %s",phone,phone1);
Max=insert(h,deal(phone,p),phone,p,Max);
Max=insert(h,deal(phone1,p),phone1,p,Max);
}
/*for(int i=0;i<p;i++)
{
printf("->>>%s %d\n",h[i].phone,h[i].num);
}
printf("the max is %d\n",Max);*/
int i,num=0;
char *Minstr=NULL;
for(i=0;i<p;i++)
{
if(h[i].num==Max)
{
if(Minstr==NULL) Minstr=h[i].phone;
else Minstr=minstr(Minstr,h[i].phone);
num++;
}
}
printf("%s %d",Minstr,Max);
if(num>1) printf(" %d",num);
return 0;
}