散列表基本原理分析&散列表应用_身份证数据系统

前言

        开一个数据结构的专栏,对经典数据结构进行分析,同时关联贫道的收费专栏--数据类型设计

引入

        散列表是最重要的数据结构之一,常用于表达数据量较大的数据集合

和其他数据集合的对比

        散列表以外的数据结构(除了图),都是基于"一次检索"的(栈和队列不需要检索,也就是不需要查找栈和队列内的数据),而其他如动态数组,树,二叉树等数据结构,在指向首个数据的地址的指针,加上一个检索条件即可查找到对应的数据(如果数据本身也是集合,那么需要进一步查找,但这不在讨论之列).

        散列表的特点是多次检索,查到对应数据

散列表的抽象

        在散列表中,数据有多层的索引,假设有4层索引检索到数据,他的形式如下

struct Whole{
    vector<Layer1> vl_1;
};

struct Layer1{
    string index;            //索引
    vector<Layer2> vl_2;
};

....2,3层略

struct Layer4{
    string index;        
    Data   data;              //数据
}

        整个数据集合由"一层索引"组成,"一层索引"由"二层索引"组成,以此类推.数据挂载到最后一层

关于索引

       1. Whole对象不需要索引,假定的是集合只存在一个,所有数据都在里面.如果做备份用其他办法

        2.索引都采用string(字符串)类型是一种简化表达,可使用其他数据类型.

身份证数据系统

        对照本国身份证,看得出他是由4层索引构建起来的.

        1.县域;2.生日域;3.出生次序;4.特殊域

        以此为依据可以设计出身份证系统的数据结构

struct Identification{       //身份证
    vector<County> vc;
};

struct County{               //县域类型
    string index;            //索引
    vector<Birthday> vb;
};


struct Birthday{             //生日类型
    string index;            //索引
    vector<Order> vo;
};

struct Order{                //生日类型
    short index;             //索引
    vector<Special> vs;
};

struct Special{              //特别提示
    string index;        
    Data   data;              //数据
}

struct Data{
    string name;              //名称  
    char   gender;            //性别
    string birthday;          //生日
    string address;           //住址
}

算法

        假设身份证数据很重要,原始数据库不能删除或修改,只定义增加与查询算法.

准备

        记录每个县域每个生日当前最大出生次序的数字,

方案一.数据库

可以在数据库中建立如下的表

生日域出生次序
20251025580
20251026475
20251027666
  
某县域(假设123456)

操作(略)

方案二:数组

        在程序中建立全局变量.假设以县域为单位,每天的人数做一个数组,也就是short num[365]={...,..};但感觉并不方便,在取数字前需要计算天数,所以做一个二维数组

//伪代码
short num[12][31]={{1月1号的数字,1月2号的数字,.....},}    //大括号里有12个大括号代表12个月

        每个县域每年一个这样的二维数组来存储出生人数.

        求得需要日子的人数,例如4月5日的最大出生次序数字,

short search_current(int month,int day,short** num){
    return *(*(num+month-1)+day-1);            //返回当前人数,传入4和5,对应num[3][4]
};

        不管是方案一还是方案二,预设的数字都是从0开始.

增加身份证号与信息

        先检索到目的县域目的生日中最大的出生次序号码(注意是用short定义的数据类型),然后在这个号码上加1作为要增加的身份证号的前17位,最后一位特殊位采用约定的号码,得到身份证号.

        数据的物理部分,假设每个县域的每个生日有一个文件夹,里面装了每个身份证号的信息(文件格式暂不考虑),按照出生次序依次排列在文件夹中.使用数组下标来查找.

        增加完一个身份证号的信息后,需要更新数据库或者全局二维数组(操作略)

查找身份证号信息

        见"准备"

=============================内容分割线↓===================================

身份证数据系统的设计重点

        回头再看,身份证数据系统的设计,重点不在代码该如何写,而是数据内容的设计

        例如:出生次序用了3位short类型,最大1000,意思是每个县域每天出生人口在1000人以内,这需要抽样,统计学的结果做支撑.如果出生人口大于1000,考虑用字符串类型,可以加A,B等字母.

        再比如特殊位如何定义?假设男性用奇数,女性用偶数,再用指定的数字表示其他信息:例如1表示男性顺产,2表示女性顺产,3表示男性剖腹产,4表示女性剖腹产,5表示男性移民,6表示女性移民等等.以上是笔者假设,不做深究.

=============================内容分割线↑===================================

小结

        散列表的基本原理,与身份证数据系统的简单思路

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

重庆彭枫

你的鼓励是我创作的动力,谢谢

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值