⭐⭐⭐浙大PTA《数据结构》中文题目集7-14 电话聊天狂人
·
考察的是查找
题干中要求:
1:在一行中给出聊天狂人的手机号码及其通话次数,其间以空格分隔。2:如果这样的人不唯一,则输出狂人中最小的号码及其通话次数,并且附加给出并列狂人的人数。
使用哈希表解决该问题
但是要注意哈希表的性能在很大程度上是取决于散列函数的效能的
下面的方法中使用了一个非常普通但常用的散列函数,即对key取余
//散列函数
unsigned long hash(const char*str){
unsigned long hash_value = 0;
while(*str != '\0'){
//直接将号码字符串逐位相加
hash_value += *(str++);
}
return hash_value % MAX;
}
运行结果

此题满分为25分,但前两个测试用例通过仅拿到了15分

需要选择一个更好的散列函数
DJB2算法
这里写得不标准,这是另一种等效的写法。具体的原理可以参见这里:
djb2:一个产生简单的随机分布的哈希函数
//散列函数
unsigned long hash(const char*str){
unsigned long hash_value = 5381;
int c;
while((c = *(str++))){
hash_value = (hash_value * 33) + c;
}
return hash_value % MAX;
}
题解如下:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#define MAX 100003
//使用哈希表完成查找任务
//拉链法解决同义词冲突问题,故使用链式结构
//结点的结构体定义
typedef struct{
char number[12];
int count;
struct Node* next;
}Node;
//哈希表
Node *hashTable[MAX] = {NULL};
//散列函数
unsigned long hash(const char*str){
unsigned long hash_value = 5381;
int c;
while((c = *(str++))){
hash_value = (hash_value * 33) + c;
}
return hash_value % MAX;
}
//核心函数
//根据输入的通话记录更新哈希表中电话号码的计数
void updateCount(const char*str){
unsigned long hash_value = hash(str);
//根据哈希值映射到哈希表中的指定位置
Node *current = hashTable[hash_value];
while(current != NULL){
//查找应该插入的位置
if(strcmp(current->number,str) == 0){
current->count ++;
return;
}
current = current->next;
}
//创建新结点,放在链首位置
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->count = 1;
strcpy(newNode->number,str);
newNode->next = hashTable[hash_value];
hashTable[hash_value] = newNode;
}
int main(){
int N;
scanf("%d",&N);
for(int i = 0; i < N; i ++){
char a[12],b[12];
scanf("%s %s",a,b);
updateCount(a);
updateCount(b);
}
//找出电话狂人
char res_number[12] = "";
int max_call = 0, creazyman = 0;
for(int i = 0; i < MAX; i++){
Node* current = hashTable[i];
while(current != NULL){
if(current->count > max_call){
max_call = current->count;
strcpy(res_number,current->number);
creazyman = 1;
}else if(current->count == max_call){
//通话的次数与当前疑似的电话狂人一样
//他可能也是电话狂人
//取两者间电话号码较小的人
if(strcmp(current->number,res_number) < 0){
strcpy(res_number,current->number);
}
creazyman++;
}
current = current->next;
}
}
if(creazyman > 1){
printf("%s %d %d\n",res_number,max_call,creazyman);
}else{
printf("%s %d\n",res_number,max_call);
}
return 0;
}
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)