基础实验5-2.2 电话聊天狂人 (25分)-散列表

解题思路:

用散列表(链表结构)

1、计算散列表长度(取比输入数据大一点的素数p)

2、构造散列函数

3、读入数据,求出散列位置插入

4、一边遍历散列表,一边求出现最多的电话狂人

#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include <math.h>
#define KeyLength 11
#define ElemType char
typedef enum {false,true
             } bool;
typedef struct LNode {
    ElemType Data[KeyLength+1];
    struct LNode *Next;
    int cnt;
}*List,LNode;
typedef struct {
    int TableSize;
    List *HashList;
}*HashTable;//判断是否是素数
bool IsPrime(int n) {
    if(n==0||n==1)
        return false;
    if(n>2) {
        int i;
        for(i=2; i<=sqrt(n)+1; i++) {
            if(n%i==0)return false;
        }
    }
    return true;
}//求比n大的第一个素数
int NextPrime(int n) {
    int i=n+1;
    while(1) {
        if(IsPrime(i))
            return i;
        i++;
    }
    return i;
}//初始化散列表
HashTable CreateHash(int size) {
    HashTable H=(HashTable)malloc(sizeof(HashTable));
    H->TableSize=NextPrime(size);
    H->HashList=(List*)malloc(sizeof(List)*H->TableSize);
    int i;
    for(i=0; i<H->TableSize; i++) {
        H->HashList[i]=(LNode*)malloc(sizeof(LNode));
        H->HashList[i]->Next=NULL;
    }
    return H;
}//构造散列函数
int Hash(HashTable H,int key) {
    return key%H->TableSize;
}//插入
void Insert(HashTable H,ElemType Value[]) {
    int key=Hash(H,atoi(Value+KeyLength-5));//atoi(Value+KeyLenght-5)取键值的最后5位
    int flag=0;
    LNode *p=H->HashList[key];
    while(p->Next) {
        if(!strcmp(p->Next->Data,Value)) {
            p->Next->cnt++;
            flag=1;
            break;
        }
        p=p->Next;
    }
    if(!flag) {
        LNode *s=(LNode *)malloc(sizeof(LNode));
        strcpy(s->Data,Value);
        s->Next=NULL;
        s->cnt=1;
        p->Next=s;
        p=s;
    }
}//遍历求电话狂人
void FindMaxCnt(HashTable H) {
    LNode *p;
    int i,maxcnt=0,count;
    char min[KeyLength+1];
    for(i=0; i<H->TableSize; i++) {
        p=H->HashList[i]->Next;
        while(p) {
            if(p->cnt>maxcnt) {
                maxcnt=p->cnt;
                count=1;
                strcpy(min,p->Data);
            } else if(p->cnt==maxcnt) {
                count++;
                if(strcmp(p->Data,min)<0) {
                    strcpy(min,p->Data);
                }
            }
            p=p->Next;
        }
    }
    printf("%s %d",min,maxcnt);
    if(count>1)
        printf(" %d",count);
}
int main() {
    int n;
    scanf("%d",&n);
    int i;
    char str[KeyLength+1];
    HashTable H=CreateHash(2*n);
    for(i=0; i<n; i++) {
        scanf("%s",str);
        Insert(H,str);
        scanf("%s",str);
        Insert(H,str);
    }
    FindMaxCnt(H);
    return 0;
}

原文地址:https://www.cnblogs.com/snzhong/p/12425735.html

时间: 2024-08-28 20:27:51

基础实验5-2.2 电话聊天狂人 (25分)-散列表的相关文章

5-14 电话聊天狂人 (25分)

给定大量手机用户通话记录,找出其中通话次数最多的聊天狂人. 输入格式: 输入首先给出正整数NN(\le 10^5≤10?5??),为通话记录条数.随后NN行,每行给出一条通话记录.简单起见,这里只列出拨出方和接收方的11位数字构成的手机号码,其中以空格分隔. 输出格式: 在一行中给出聊天狂人的手机号码及其通话次数,其间以空格分隔.如果这样的人不唯一,则输出狂人中最小的号码及其通话次数,并且附加给出并列狂人的人数. 输入样例: 4 13005711862 13588625832 135057118

PTA 5-14 电话聊天狂人 (25分)

给定大量手机用户通话记录,找出其中通话次数最多的聊天狂人. 输入格式: 输入首先给出正整数NN(\le 10^5≤10?5??),为通话记录条数.随后NN行,每行给出一条通话记录.简单起见,这里只列出拨出方和接收方的11位数字构成的手机号码,其中以空格分隔. 输出格式: 在一行中给出聊天狂人的手机号码及其通话次数,其间以空格分隔.如果这样的人不唯一,则输出狂人中最小的号码及其通话次数,并且附加给出并列狂人的人数. 输入样例: 4 13005711862 13588625832 135057118

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

给定大量手机用户通话记录,找出其中通话次数最多的聊天狂人. 输入格式: 输入首先给出正整数N(≤),为通话记录条数.随后N行,每行给出一条通话记录.简单起见,这里只列出拨出方和接收方的11位数字构成的手机号码,其中以空格分隔. 输出格式: 在一行中给出聊天狂人的手机号码及其通话次数,其间以空格分隔.如果这样的人不唯一,则输出狂人中最小的号码及其通话次数,并且附加给出并列狂人的人数. 输入样例: 4 13005711862 13588625832 13505711862 13088625832 1

基础实验3-2.3 共享后缀的链表 (25分)

有一种存储英文单词的方法,是把单词的所有字母串在一个单链表上.为了节省一点空间,如果有两个单词有同样的后缀,就让它们共享这个后缀.下图给出了单词“loading”和“being”的存储形式.本题要求你找出两个链表的公共后缀. 函数接口定义: PtrToNode Suffix( List L1, List L2 ); 其中List结构定义如下: typedef struct Node *PtrToNode; struct Node { ElementType Data; /* 存储结点数据 */

电话聊天狂人

11-散列1 电话聊天狂人   (25分) 给定大量手机用户通话记录,找出其中通话次数最多的聊天狂人. 输入格式: 输入首先给出正整数N(≤10?5??),为通话记录条数.随后N行,每行给出一条通话记录.简单起见,这里只列出拨出方和接收方的11位数字构成的手机号码,其中以空格分隔. 输出格式: 在一行中给出聊天狂人的手机号码及其通话次数,其间以空格分隔.如果这样的人不唯一,则输出狂人中最小的号码及其通话次数,并且附加给出并列狂人的人数. 输入样例: 4 13005711862 135886258

7-14 电话聊天狂人

7-14 电话聊天狂人(25 分) 给定大量手机用户通话记录,找出其中通话次数最多的聊天狂人. 输入格式: 输入首先给出正整数N(≤10?5??),为通话记录条数.随后N行,每行给出一条通话记录.简单起见,这里只列出拨出方和接收方的11位数字构成的手机号码,其中以空格分隔. 输出格式: 在一行中给出聊天狂人的手机号码及其通话次数,其间以空格分隔.如果这样的人不唯一,则输出狂人中最小的号码及其通话次数,并且附加给出并列狂人的人数. 输入样例: 4 13005711862 13588625832 1

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

给定大量手机用户通话记录,找出其中通话次数最多的聊天狂人. 输入格式: 输入首先给出正整数N(≤10?5??),为通话记录条数.随后N行,每行给出一条通话记录.简单起见,这里只列出拨出方和接收方的11位数字构成的手机号码,其中以空格分隔. 输出格式: 在一行中给出聊天狂人的手机号码及其通话次数,其间以空格分隔.如果这样的人不唯一,则输出狂人中最小的号码及其通话次数,并且附加给出并列狂人的人数. 输入样例: 4 13005711862 13588625832 13505711862 1308862

基础实验2-2.1 整数的分类处理 (20分)

给定 N 个正整数,要求你从中得到下列三种计算结果: A1 = 能被 3 整除的最大整数 A2 = 存在整数 K 使之可以表示为 3K+1 的整数的个数 A3 = 存在整数 K 使之可以表示为 3K+2 的所有整数的平均值(精确到小数点后 1 位) 输入格式: 输入首先在第一行给出一个正整数 N,随后一行给出 N 个正整数.所有数字都不超过 100,同行数字以空格分隔. 输出格式: 在一行中顺序输出 A1.A2.A3的值,其间以 1 个空格分隔.如果某个数字不存在,则对应输出NONE. 输入样例

基础实验5-2.1 整型关键字的平方探测法散列 (25分)

#include <stdio.h> #include <math.h> #include <string.h> #include <malloc.h> typedef enum {false,true } bool; bool IsPrime(int n) { if(n==0||n==1) return false; if(n>2) { int i; for(i=2; i<=sqrt(n)+1; i++) { if(n%i==0)return