整活向:使用一个64位整型来存储电话号码
前因
今天在吃饭的时候刷着一条提问,说是电话号码用整型存储好还是字符串String类型存储好。许多人都是采用字符串类型进行存储,因为int32长度范围不够,即使用int64存储有些特殊符号也不好办。
于是我想整个活,用编码的方式将电话号码存储到一个整型中去。
分析
我们可以看电话号码的数字总共有10种,从0到9,而特殊符号#*±,总共14种,可以用4个二进制位进行编码表示。
字符 | 二进制编码(4 位) |
---|---|
1 | 0001 |
2 | 0010 |
3 | 0011 |
4 | 0100 |
5 | 0101 |
6 | 0110 |
7 | 0111 |
8 | 1000 |
9 | 1001 |
0 | 1010 |
* | 1011 |
+ | 1100 |
= | 1101 |
- | 1110 |
然后最长的电话号码不超过11个字符,即使算上-符号也只有13个字符左右,因此按15个字符算,刚好60个二进制位,对于64位整型,最后剩下的4位还可以用来表示字符串长度用于标记有效的二进制位。
我们来举个例子,假设某人电话号码为2,那么就有1个字符,表示长度的二进制为0001,对于电话号码字符部分编码就是0010,那么64位整数转成二进制就是00100001。
我们在解码的时候就可以先读取低位上的4个二进制位获取长度,然后对这个长度乘4(十进制运算)得到有效的电话号码编码的二进制位数,在根据上表进行解码得到原本的电话号码。对于00100001来说,低4位为0001,转换成十进制为1,乘4就变成了4,表示后面4个二进制位是有效位,再取出0010转换成字符串就是2。
代码
我用C++简单写了写:
#include <iostream>
#include <map>
#include <string>
#include <bitset>
// 创建字符到整数的编码映射关系,这里简单示例用4位二进制对应的整数来编码
std::map<char, int> encodingMap = {
{
'1', 1},
{
'2', 2},
{
'3', 3},
{
'4', 4},