目录

  • 题目描述
  • 解题思路

题目描述

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

输入格式:
输入首先给出正整数N(≤10​5​​ ),为通话记录条数。随后N行,每行给出一条通话记录。简单起见,这里只列出拨出方和接收方的11位数字构成的手机号码,其中以空格分隔。

输出格式:
在一行中给出聊天狂人的手机号码及其通话次数,其间以空格分隔。如果这样的人不唯一,则输出狂人中最小的号码及其通话次数,并且附加给出并列狂人的人数。

输入样例:

4
13005711862 13588625832
13505711862 13088625832
13588625832 18087925832
15005713862 13588625832

输出样例:

#include<stdio.h>
#include<malloc.h>
#include<string.h>
#include<math.h>
#include<stdbool.h>#define KEYLENGTH 11
#define MAXTABLESIZE 100000
#define MAXD 5typedef char ElementType[KEYLENGTH+1]; /* char数组结尾是/0 */
typedef int index;typedef struct LNode *PtrToLNode;
struct LNode{ElementType Data;PtrToLNode Next;int Count;
};
typedef PtrToLNode Position;
typedef PtrToLNode List;typedef struct TblNode *HashTable;
struct TblNode{int TableSize;List Heads;
};int NextPrime(int N)
{ /* 返回大于N且不超过MAXTABLESIZE的素数 */int i, p = (N%2) ? N+2 : N+1; /* 从大于N的下一个奇数开始,因为偶数肯定不是素数 */while( p <= MAXTABLESIZE ){for( i=(int)sqrt(p); i>2; --i )if( !(p%i) ) break;if ( i==2 ) break; /* 说明p是素数,退出while循环 */else p += 2; /* p不是素数,尝试下一个奇数 */}return p;
}HashTable CreateTable( int TableSize )
{HashTable H;int i;H = (HashTable)malloc(sizeof(struct TblNode));H->TableSize = NextPrime(TableSize);H->Heads = (List)malloc(H->TableSize*sizeof(struct LNode));for(i=0; i<H->TableSize; ++i){H->Heads[i].Data[0] = '\0';H->Heads[i].Next = NULL;H->Heads[i].Count = 0;}return H;
}index Hash(int key, int tablesize)
{ /* 除留取余数法散列函数 */return key % tablesize;
}Position Find( HashTable H, ElementType Key )
{Position P;index Pos;/* 初始散列位置 */Pos = Hash(atoi(Key+KEYLENGTH-MAXD),H->TableSize); /* atoi函数将指向的字符串转换为一个int正数 */P = H->Heads[Pos].Next;while( P && strcmp(Key, P->Data) ) /* strcmp比较两个字符串,相等输出0 */P = P->Next;return P;
}bool Insert( HashTable H, ElementType Key )
{Position P, NewCell;index Pos;P = Find(H,Key);if( !P ){ /* 关键词没有找到,P返回的是NULL */NewCell = (Position)malloc(sizeof(struct LNode));strcpy(NewCell->Data,Key);NewCell->Count = 1;Pos = Hash(atoi(Key+KEYLENGTH-MAXD),H->TableSize);NewCell->Next = H->Heads[Pos].Next;H->Heads[Pos].Next = NewCell;return true;}else{ /* 关键词已经存在 */++P->Count;return false;}
}ScanfAndOutput(HashTable H)
{int i, MaxCnt = 0, PCnt = 0;ElementType MinPhone;List Ptr;MinPhone[0] = '\0';for(i=0; i!=H->TableSize; ++i){Ptr = H->Heads[i].Next;while(Ptr){if(Ptr->Count>MaxCnt){MaxCnt = Ptr->Count;strcpy(MinPhone,Ptr->Data);PCnt = 1;}else if(Ptr->Count == MaxCnt){ /* 另一个人也同样电话狂 */++PCnt;/* 电话狂人计数 */if( strcmp(MinPhone,Ptr->Data) > 0 ) /* 找到最小电话号码 */strcpy(MinPhone,Ptr->Data);}Ptr = Ptr->Next;}}printf("%s %d",MinPhone,MaxCnt);if(PCnt>1)printf(" %d",PCnt);
}void DestroyTable(HashTable H)
{int i;List Ptr, DestroyPtr;for(i=0; i!=H->TableSize; ++i){Ptr = H->Heads[i].Next;while(Ptr){DestroyPtr = Ptr;Ptr = Ptr->Next;free(DestroyPtr);}}free(H->Heads);free(H);
}int main()
{int N, i;ElementType Key;HashTable H;scanf("%d",&N);H = CreateTable(N*2);for( i=0; i!=N; ++i ){scanf("%s",Key);Insert(H,Key);scanf("%s",Key);Insert(H,Key);}ScanfAndOutput(H);DestroyTable(H);return 0;
}

解题思路

将电话号码的后五位作为关键字,用atoi函数转化成五位int型整数,取余法获得位置,解决冲突的方法是分离链接法。

DestroyTable函数先free头结点后连接的所有节点,然后free头结点数组,最后free整个H。

十一、散列查找:电话聊天狂人相关推荐

  1. 算法 散列1 电话聊天狂人

    全部每周作业和视频思考题答案和解析 见 浙江大学 数据结构 思考题+每周练习答案 题目:给定大量手机用户通话记录,找出其中通话次数最多的聊天狂人. 输入格式: 输入首先给出正整数N(≤10​5​​), ...

  2. PTA 11-散列1 电话聊天狂人

    PTA 11-散列1 电话聊天狂人 文章目录 PTA 11-散列1 电话聊天狂人 思路 Code 给定大量手机用户通话记录,找出其中通话次数最多的聊天狂人. 输入格式: 输入首先给出正整数N(≤10^ ...

  3. 11-散列1 电话聊天狂人 (25 分) (C语言)

    浙大版<C语言程序设计实验与习题指导(第3版)>题目集 11-散列1 电话聊天狂人 (25 分) 二.题解 c代码 11-散列1 电话聊天狂人 (25 分) 给定大量手机用户通话记录,找出 ...

  4. (C语言详解)11-散列1 电话聊天狂人(小白实现详细解释)

    本博文源于浙江大学<数据结构>.电话聊天狂人是非常有趣的一道题.姥姥在小白专场里从main函数搭建.重要函数编写.模块的改变与裁剪非常仔细的说明,下面就给出详细指导: 博主在前篇博文已经将 ...

  5. 《数据结构》11-散列1 电话聊天狂人

    题目 给定大量手机用户通话记录,找出其中通话次数最多的聊天狂人. 输入格式: 输入首先给出正整数N(≤10​5​^5​5​​ ),为通话记录条数.随后N行,每行给出一条通话记录.简单起见,这里只列出拨 ...

  6. 11-散列1 电话聊天狂人

    给定大量手机用户通话记录,找出其中通话次数最多的聊天狂人. 输入格式: 输入首先给出正整数N(≤10​^5​​),为通话记录条数.随后N行,每行给出一条通话记录.简单起见,这里只列出拨出方和接收方的1 ...

  7. 11-散列1 电话聊天狂人 (25 分)

    给定大量手机用户通话记录,找出其中通话次数最多的聊天狂人. 输入格式: 输入首先给出正整数N(≤),为通话记录条数.随后N行,每行给出一条通话记录.简单起见,这里只列出拨出方和接收方的11位数字构成的 ...

  8. 11-散列1 电话聊天狂人分数 25作者 DS课程组单位 浙江大学

    给定大量手机用户通话记录,找出其中通话次数最多的聊天狂人. 输入格式: 输入首先给出正整数N(≤105),为通话记录条数.随后N行,每行给出一条通话记录.简单起见,这里只列出拨出方和接收方的11位数字 ...

  9. 11-散列1 电话聊天狂人 (25分)

    给定大量手机用户通话记录,找出其中通话次数最多的聊天狂人. 输入格式: 输入首先给出正整数N(≤10 ^5),为通话记录条数.随后N行,每行给出一条通话记录.简单起见,这里只列出拨出方和接收方的11位 ...

  10. PTA 查找(散列查找)

    散列查找: 根据散列函数确定关键词key的存储位置,将key存储在一张hash哈希表内,然后根据一定的规则(线性探测,平方探测,分离链接等)来规避相同key的数据之间的冲突. 如上图,散列表的性能和装 ...

最新文章

  1. SpringMVC 学习系列 (3) 之 URL请求到Action的映射规则
  2. 商丘网络推广是如何做好网站优化的关键词布局的呢?
  3. 《穿越计算机的迷雾》读书笔记三
  4. tuple 方法总结整理
  5. PostMessage与SendMessage
  6. 如何用“区块链+稳定币”技术来提升资产证券化市场运作效率
  7. 资金时间价值的计算机应用视频讲解,第八章资金时间价值与方案经济比选20161018讲解.ppt...
  8. MySQL Connector/C++入门教程(上)
  9. 理解android.intent.action.MAIN 与 android.intent.category.LAUNCHER
  10. MMO游戏技能攻击区域的计算2--给地图划分格子
  11. python爬取豆瓣TOP250
  12. 阿里巴巴Java开发手册终极版v1.3.0(百度网盘资源)
  13. python跳一跳编程构造_Python玩“跳一跳” iOS+Win 硬件实现
  14. ChinaSoft 论坛巡礼 | 软件智能合成理论与方法
  15. ToothFairy for Mac(一键连接蓝牙设备软件) v2.4.5免激活版
  16. iptable 笔记
  17. 掘金 AMA:听闲鱼客户端架构师--邬吉风聊 Flutter 和移动端开发那些事
  18. eclipse取消默认工作空间的两种方法
  19. (转)MultipleOutputFormat和MultipleOutputs
  20. 【推荐】真正的安卓网络摄像机(Android IPCamera)任意浏览器输入IP地址即可观看视频

热门文章

  1. 安装mysql odbc重启mssql_关于php连接mssql:pdo odbc sql server
  2. input @矿粉,想换哪种颜色的矿粉呢?(红/黄/蓝/绿)
  3. Revit做基坑放坡开挖方法及快速生成基坑
  4. 2059 - authentication plugin...错误解决方法
  5. 车辆检测站管理系统如何选择?
  6. 服装V2版:删除商品时提示“该商品已发生业务关系,不能删除”,怎么才可以删除?
  7. 异地查封保管、异地看样 京东物流助力司法执行
  8. codeforces 1311D(暴力)
  9. java html文本编辑器,基于Java WebHTML在线文本编辑器解决方案.doc
  10. dsge模型难做吗_请在针对DSGE模型学习的建议性计划--转自人大经济论坛