哈希算法 C语言 (数组实现)

7-17 电话聊天狂人(25 分)

给定大量手机用户通话记录,找出其中通话次数最多的聊天狂人。

输入格式:

输入首先给出正整数N(≤10​5​​),为通话记录条数。随后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;
}

 

  • 2
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值