美文网首页
记腾讯面试题-整形压缩

记腾讯面试题-整形压缩

作者: 布灵不灵的丙丙 | 来源:发表于2020-05-25 21:55 被阅读0次

    背景:

    • 对于一个整数,以uint32为例,其占用4字节,在存储的时候如果都使用4字节来存储uint32类型的数据,有些时候会存在浪费,因为并不是所有整形数据有效位都占用4个字节,例如像0x01用单个字节可以表达,而0x1ff则用2个字节就可以表达。而实际情况中,除了一些hash值等有可能占满4字节,大多数情况下我们的uint32数据是用不到4字节的。为解决这种情况,可以通过一个整形压缩的算法来解决内存/磁盘占用情况。

    实现方式:

    • 使用低7位来表达有效值,高位来表达编码是否完成,如果高位为0代表编码完成,高位为1代表编码未完成,这样在解码的时候便可以通过遍历字节的高位来判断是否完成解码
    • 由于有效位只有7位,所以一个uint32的整形最少可以由1个字节完成编码,最多由5个字节完成编码,即 1~5个字节表示;类推uint64位的整形,则可以由 1 ~ 10个字节表示

    编码实现:

    void chartobs(char  ch, char* ps)
    {
        const int  size = 8 * sizeof(char);
        for (int i = 7; i >= 0; i--, ch >>= 1)
        {
            ps[i] = (01 & ch) + '0';
        }
        ps[size] = '\0';
    }
    
    void itobs(int  n, char* ps)
    {
        const int  size = 8 * sizeof(int);
        for (int i = size - 1; i >= 0; i--, n >>= 1)
        {
            ps[i] = (01 & n) + '0';
        }
        ps[size] = '\0';
    }
    
    void show_bstr(const char* str)
    {
        size_t i = 0;
        while (str[i])
        {
            putchar(str[i]);
            if (++i % 8 == 0 && str[i])
                putchar(' ');
        }
        printf("\n");
    }
    //将一个四字节的整形数值压缩成1~5个字节
    size_t encode(unsigned int num, char *buf)
    {
        size_t len = 0;
    for (int a = sizeof(unsigned int); a >= 0; a--)
        {
            char c;
            c = num >> (a * 7) & 0x7f;
            if (c == 0x00 && len == 0)
            {
                char szDest[16] = { 0 };
                chartobs(c, szDest);
                cout << szDest << " ";
                continue;
            }
            //处理高位标识
            if (a == 0)
                c &= 0x7f;
            else
                c |= 0x80;
            buf[len] = c;
            len++;
    
            char szDest[16] = { 0 };
            chartobs(c, szDest);
            cout << szDest << " ";
        }
        cout << endl;
        if (len == 0)
        {
            len++;
            buf[0] = 0;
        }
        return len;
    }
    
    //将一个1~5个字节的值还原成四字节的整形值
    unsigned int decode(char *buf, size_t len)
    {
        unsigned int num = 0;
        for (int index = 0; index < (int)len; index++)
        {
            char c = *(buf + index);
            num = num << 7;
    
            c &= 0x7f;
            num |= c;
        }
        cout << "decode: " << num << endl;
        return num;
    }
    
    

    测试用例:

    int main(void)
    {
        unsigned int num = 300;
        char szShowStr[64] = { 0 };
        itobs(num, szShowStr);
        show_bstr(szShowStr);
    
        char szDest[5] = { 0 };
        size_t len = encode(num, szDest);
    
        system("pause");
        return 0;
    }
    
    

    相关文章

      网友评论

          本文标题:记腾讯面试题-整形压缩

          本文链接:https://www.haomeiwen.com/subject/eynuahtx.html