hash基本练习

引用块内容

姓名与身份证号
C/C++ 1.5s, JAVA 3s
1个case
250MB memory限制

某公司有10万员工,需要一个小系统对姓名、身份证号进行查询。
员工信息:
每名员工的信息使用两行表示,第一行是姓名,是一个长度为23的大写字符串;第二行是身份证号,由18个长度为0~9的数字组成
身份证号保证唯一
姓名可能产生重复

题目输入:
题目使用input.txt进行输入,输入有400,000行
前200,000行,是100,000个员工的信息
中间100,000行,是100,000个身份证号,要求输出每个身份证号对应的姓名
最后100,000行,是100,000个姓名字符串,要求输出每个名字有多少人使用

题目输出:
输出分为200,000行
前100,000行,输出100,000个姓名字符串
后100,000行,输出100,000个整形数,对应使用每个名字的人数
输入要求:
所有输出,请重定向至result.txt进行保存
freopen(“e:/result.txt”, “w”, stdout);

提示:
由于输入规模较大,C/C++请使用scanf进行读入,java请使用BufferRead进行读入
C/C++:
char str[24];
scanf(“%s”, &str);
long long int ID;
scanf(“%lld”, & ID);

JAVA:
new BufferedReader(new FileReader(“input.txt”));


//587.000000ms
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>

#define SIZE 100001

typedef struct Node{
    char name[24];
    char id[19];
    Node* next;
    //Node* prev;
};

typedef struct NAME{
    char name[24];
    int count;
    NAME* next;
    //NAME* prev;
};

Node idHashTable[SIZE];
NAME nameHashTable[SIZE];

Node idHashPool[SIZE];
NAME nameHashPool[SIZE];

int HashIdIndex = 0;
int HashNameIndex = 0;

Node * getIdNewNode()
{
    return &idHashPool[HashIdIndex++];
}

NAME * getNameNewNode()
{
    return &nameHashPool[HashNameIndex++];
}


void initHashTable(){
    for (int i = 0; i < SIZE; i++){
        idHashTable[i].name[24] = '\0';
        idHashTable[i].id[19] = '\0';
        idHashTable[i].next = &idHashTable[i];

        nameHashTable[i].name[24] = '\0';
        nameHashTable[i].count = 0;
        nameHashTable[i].next = &nameHashTable[i];
    }
}

int getKey(char* id){
    int key = 0;
    while (*id != '\0'){
        key = (key * 10 + (*(id++) - '0')) % SIZE;
    }
    return key%SIZE;
}

int getNameKey(char* name){
    int key = 0;
    while (*name != '\0'){
        key = (key * 26 + (*(name++) - 'A')) % SIZE;
    }
    return key%SIZE;
}

void copy(char a[], char b[]){
    for (int i = 0; a[i] != '\0'; i++){
        b[i] = a[i];
    }
}

void insert(char* name, char *id){
    //Node* node = new Node();
    Node * newNode = getIdNewNode();
    copy(id, newNode->id);
    copy(name, newNode->name);

    int key = getKey(id);
    Node* cur = &idHashTable[key];

    newNode->next = cur->next;
    cur->next = newNode;
    //node->next = cur->next;
    //node->prev = cur;
    //cur->next->prev = node;
    //cur->next = node;
}


int isSame(char a[], char b[]){
    for (int i = 0; a[i] != '\0'; i++){
        if (a[i] != b[i]){
            return 0;
        }
    }
    return 1;
}

void insertName(char* name){
    //NAME* node = new NAME();
    NAME * newNameNode = getNameNewNode();
    copy(name, newNameNode->name);

    int key = getNameKey(name);
    NAME* cur = nameHashTable[key].next;
    while (cur != &nameHashTable[key]){
        if (isSame(name, cur->name)){
            cur->count++;
            return;
        }
        cur = cur->next;
    }

    newNameNode->count = 1;
    newNameNode->next = cur->next;
    cur->next = newNameNode;
    //node->next = cur->next;
    //node->prev = cur;
    //cur->next->prev = node;
    //cur->next = node;
}

Node* search(char* id){
    int key = getKey(id);
    Node* cur = idHashTable[key].next;
    while (cur != &idHashTable[key]){
        if (isSame(id, cur->id)){
            return cur;
        }
        cur = cur->next;
    }
    return NULL;
}

int searchName(char* name){
    int key = getNameKey(name);
    NAME* cur = nameHashTable[key].next;
    while (cur != &nameHashTable[key]){
        if (isSame(name, cur->name)){
            return cur->count;
        }
        cur = cur->next;
    }
    return 0;
}
#include<time.h>
int main(){
    time_t start = clock();
    freopen("input.txt", "r", stdin);
    freopen("d:/result.txt", "w", stdout);
    char name[24];
    char id[19];
    initHashTable();
    for (int i = 0; i < 100000; i++){
        scanf("%s%s", name, id);
        insert(name, id);
        insertName(name);
    }

    for (int i = 0; i < 100000; i++){
        scanf("%s", id);
        printf("%s\n", search(id)->name);
    }

    for (int i = 0; i < 100000; i++){
        scanf("%s", name);
        printf("%d\n", searchName(name));
    }
    time_t end = clock();
    printf("%llfms", (double)(end - start));
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值