十一、散列查找:电话聊天狂人
目录
- 题目描述
- 解题思路
题目描述
给定大量手机用户通话记录,找出其中通话次数最多的聊天狂人。
输入格式:
输入首先给出正整数N(≤105 ),为通话记录条数。随后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 电话聊天狂人
全部每周作业和视频思考题答案和解析 见 浙江大学 数据结构 思考题+每周练习答案 题目:给定大量手机用户通话记录,找出其中通话次数最多的聊天狂人. 输入格式: 输入首先给出正整数N(≤105), ...
- PTA 11-散列1 电话聊天狂人
PTA 11-散列1 电话聊天狂人 文章目录 PTA 11-散列1 电话聊天狂人 思路 Code 给定大量手机用户通话记录,找出其中通话次数最多的聊天狂人. 输入格式: 输入首先给出正整数N(≤10^ ...
- 11-散列1 电话聊天狂人 (25 分) (C语言)
浙大版<C语言程序设计实验与习题指导(第3版)>题目集 11-散列1 电话聊天狂人 (25 分) 二.题解 c代码 11-散列1 电话聊天狂人 (25 分) 给定大量手机用户通话记录,找出 ...
- (C语言详解)11-散列1 电话聊天狂人(小白实现详细解释)
本博文源于浙江大学<数据结构>.电话聊天狂人是非常有趣的一道题.姥姥在小白专场里从main函数搭建.重要函数编写.模块的改变与裁剪非常仔细的说明,下面就给出详细指导: 博主在前篇博文已经将 ...
- 《数据结构》11-散列1 电话聊天狂人
题目 给定大量手机用户通话记录,找出其中通话次数最多的聊天狂人. 输入格式: 输入首先给出正整数N(≤105^55 ),为通话记录条数.随后N行,每行给出一条通话记录.简单起见,这里只列出拨 ...
- 11-散列1 电话聊天狂人
给定大量手机用户通话记录,找出其中通话次数最多的聊天狂人. 输入格式: 输入首先给出正整数N(≤10^5),为通话记录条数.随后N行,每行给出一条通话记录.简单起见,这里只列出拨出方和接收方的1 ...
- 11-散列1 电话聊天狂人 (25 分)
给定大量手机用户通话记录,找出其中通话次数最多的聊天狂人. 输入格式: 输入首先给出正整数N(≤),为通话记录条数.随后N行,每行给出一条通话记录.简单起见,这里只列出拨出方和接收方的11位数字构成的 ...
- 11-散列1 电话聊天狂人分数 25作者 DS课程组单位 浙江大学
给定大量手机用户通话记录,找出其中通话次数最多的聊天狂人. 输入格式: 输入首先给出正整数N(≤105),为通话记录条数.随后N行,每行给出一条通话记录.简单起见,这里只列出拨出方和接收方的11位数字 ...
- 11-散列1 电话聊天狂人 (25分)
给定大量手机用户通话记录,找出其中通话次数最多的聊天狂人. 输入格式: 输入首先给出正整数N(≤10 ^5),为通话记录条数.随后N行,每行给出一条通话记录.简单起见,这里只列出拨出方和接收方的11位 ...
- PTA 查找(散列查找)
散列查找: 根据散列函数确定关键词key的存储位置,将key存储在一张hash哈希表内,然后根据一定的规则(线性探测,平方探测,分离链接等)来规避相同key的数据之间的冲突. 如上图,散列表的性能和装 ...
最新文章
- SpringMVC 学习系列 (3) 之 URL请求到Action的映射规则
- 商丘网络推广是如何做好网站优化的关键词布局的呢?
- 《穿越计算机的迷雾》读书笔记三
- tuple 方法总结整理
- PostMessage与SendMessage
- 如何用“区块链+稳定币”技术来提升资产证券化市场运作效率
- 资金时间价值的计算机应用视频讲解,第八章资金时间价值与方案经济比选20161018讲解.ppt...
- MySQL Connector/C++入门教程(上)
- 理解android.intent.action.MAIN 与 android.intent.category.LAUNCHER
- MMO游戏技能攻击区域的计算2--给地图划分格子
- python爬取豆瓣TOP250
- 阿里巴巴Java开发手册终极版v1.3.0(百度网盘资源)
- python跳一跳编程构造_Python玩“跳一跳” iOS+Win 硬件实现
- ChinaSoft 论坛巡礼 | 软件智能合成理论与方法
- ToothFairy for Mac(一键连接蓝牙设备软件) v2.4.5免激活版
- iptable 笔记
- 掘金 AMA:听闲鱼客户端架构师--邬吉风聊 Flutter 和移动端开发那些事
- eclipse取消默认工作空间的两种方法
- (转)MultipleOutputFormat和MultipleOutputs
- 【推荐】真正的安卓网络摄像机(Android IPCamera)任意浏览器输入IP地址即可观看视频
热门文章
- 安装mysql odbc重启mssql_关于php连接mssql:pdo odbc sql server
- input @矿粉,想换哪种颜色的矿粉呢?(红/黄/蓝/绿)
- Revit做基坑放坡开挖方法及快速生成基坑
- 2059 - authentication plugin...错误解决方法
- 车辆检测站管理系统如何选择?
- 服装V2版:删除商品时提示“该商品已发生业务关系,不能删除”,怎么才可以删除?
- 异地查封保管、异地看样 京东物流助力司法执行
- codeforces 1311D(暴力)
- java html文本编辑器,基于Java WebHTML在线文本编辑器解决方案.doc
- dsge模型难做吗_请在针对DSGE模型学习的建议性计划--转自人大经济论坛