[算法题] 字节流解析

字节流解析

题目标题:

  • 根据数值占用BIT数,按顺序从输入字节流中解析出对应数值,解析顺序按输入数组astElement索引升序。

详细描述:

  • 接口说明

原型:

voidDecode(unsignedintuiIutputLen,unsignedcharaInputByte[],unsignedintuiElementNum,ELEMENT_STRU astElement[]);

输入参数:

unsignedintuiIutputLen:字节数组(流)长度

unsignedcharaInputByte:字节数组(流)

unsignedintuiElementNum:解析数值个数

ELEMENT_STRU astElement[]:数值的结构数组指针,含义如下

     Struct
{
     unsignedintuiElementLength;    //表示uiElementValue占用BIT数,范围1~32
     unsignedintuiElementValue;     //从字节流中按顺序解析的数值,用于输出
}ELEMENT_STRU;

输出参数(指针指向的内存区域保证有效):

参见上述ELEMENT_STRU中uiElementValue描述

返回值:

Void

举例:

输入:

字节数组长度uiIutputLen为2;

字节数组aInputByte[2]为{0x62, 0x80},对应二进制为“01100010 1 000 0000”;

解析数值个数uiElementNum为2;

数值[0]的值占4个bit,即astElement[0].uiElementLength = 4;

数值[1]的值占5个bit,即astElement[1].uiElementLength = 5;

输出:

数值[0]的值为6,二进制为“0110”,即astElement[0].uiElementValue = 6;

数值[1]的值为5,二进制为“0010 1”,即astElement[1].uiElementValue = 5。

 //OJ.h

#ifndef __OJ_H__
#define __OJ_H__

typedef struct
{
    unsigned int uiElementLength; //表示数值uiElementValue占用BIT数,范围1~32
    unsigned int uiElementValue; //表示编码的数值
}ELEMENT_STRU;

void Decode(unsigned int uiIutputLen, unsigned char aInputByte[], unsigned int uiElementNum, ELEMENT_STRU astElement[]);


#endif

 //OJ.cpp

#include "OJ.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define BITS_NUM_OF_BYTE    (8)
#define BITS_MALLOC_SIZE    (9)
#define ELEM_MAX_SIZE       (32)
#define ELEM_MALLOC_SIZE    (33)


/*******************************************************************************
Func Name       : ByteTransToBits
Date Created    : 2013-11-29
Author          : Description     : 
Input           : 
    unsigned char   aInputByte[],   待转化的字节
    unsigned int    uiIutputLen,    实际长度
Output          : 
    char            *pcStrBuf,      转化后的二进制字符串
Return          : 
Caution         :
History         :
Date                Author                      Modification
*******************************************************************************/
void ByteTransToBits
(
    unsigned char   aInputByte[],
    unsigned int    uiIutputLen,
    char            *pcStrBuf
)
{
    unsigned int i      = 0;
    unsigned int j      = 0;
    unsigned int index  = 0;
    char acTmp[BITS_MALLOC_SIZE] = {0};
    for (i = 0; i < uiIutputLen; i++)
    {
        _itoa_s(aInputByte[i], acTmp, BITS_MALLOC_SIZE, 2);
        if (strlen(acTmp) < BITS_NUM_OF_BYTE)   //如果itoa转化的二进制串不满8位,则在头部加'0'
        {
            j = BITS_NUM_OF_BYTE - (unsigned int)strlen(acTmp);
            while (j-- > 0)
            {
                pcStrBuf[index] = '0';
                index++;
            }
            memcpy(pcStrBuf + index, acTmp, (unsigned int)strlen(acTmp));
            index += (unsigned int)strlen(acTmp);
            memset(acTmp, 0, BITS_MALLOC_SIZE);
            continue;
        }
        memcpy(pcStrBuf + index, acTmp, strlen(acTmp));
        memset(acTmp, 0, BITS_MALLOC_SIZE);
        printf("\n%s : %d", acTmp, strlen(acTmp));
    }
}

/*******************************************************************************
Func Name       : BitsTransToNum
Date Created    : 2013-11-29
Author          : Description     : 根据数值所占位数,截取二进制字符串,获取真实数值
Input           : 
    char            *pcStrBuf,      二进制字符串
    unsigned int    uiElementNum,   有效二进制位数
       
Output          : 
    ELEMENT_STRU    astElement[],   数值结构体
Return          : 
Caution         :
History         :
Date                Author                      Modification
*******************************************************************************/
void BitsTransToNum
(
    char            *pcStrBuf,
    unsigned int    uiElementNum,
    ELEMENT_STRU    astElement[]
)
{
    int             iNum    = 0;
    unsigned int    i       = 0;
    unsigned int    j       = 0;
    unsigned int    index   = 0;
    char acNum[ELEM_MALLOC_SIZE] = {0};
    index = 0;
    for (i = 0; i < uiElementNum; i++)
    {
        iNum = 0;
        memset(acNum, 0, ELEM_MALLOC_SIZE);
        if (astElement[i].uiElementLength < 1 || astElement[i].uiElementLength > ELEM_MAX_SIZE)
        {
            return;
        }
        memcpy(acNum, pcStrBuf + index, astElement[i].uiElementLength);
        index += astElement[i].uiElementLength;
        for (j = 0; j < (unsigned int)strlen(acNum); j++)
        {
            iNum = iNum << 1;
            iNum = iNum + acNum[j] - '0';
        }
        astElement[i].uiElementValue = iNum;
    }
}

/*
功能: 根据数值占用BIT数,按顺序从输入字节流中解析出对应数值,解析顺序按输入数组astElement索引升序
    
输入:
unsigned int uiIutputLen:字节数组(流)长度
unsigned char aInputByte:字节数组(流)
unsigned int uiElementNum:解析数值个数
ELEMENT_STRU astElement[]:数值的结构数组指针,含义如下
Struct
{
    unsigned int uiElementLength;   //表示uiElementValue占用BIT数,范围1~32
    unsigned int uiElementValue;    //从字节流中按顺序解析的数值,用于输出
}ELEMENT_STRU;

输出:参见上述ELEMENT_STRU中uiElementValue描述

返回:void
*/
void Decode
(
    unsigned int uiIutputLen,
    unsigned char aInputByte[], 
    unsigned int uiElementNum,
    ELEMENT_STRU astElement[]
)
{
    char *pcStrBuf = NULL;

    if (NULL == aInputByte || NULL == astElement || 0 >= uiIutputLen || 0 >= uiElementNum)
    {
        return;
    }

    /* 步骤0. 初始化字符串指针 */
    pcStrBuf = (char*) malloc (uiIutputLen * BITS_MALLOC_SIZE);
    if (NULL == pcStrBuf)
    {
        return;
    }
    memset(pcStrBuf, 0, uiIutputLen * BITS_MALLOC_SIZE);

    /* 步骤1. 把字节数组aInputByte转为二进制字符串,存入pcStrBuf */
    ByteTransToBits(aInputByte, uiIutputLen, pcStrBuf);

    /* 步骤2. 根据数值所占位数,截取二进制字符串,获取真实数值 */
    BitsTransToNum(pcStrBuf, uiElementNum, astElement);

    free(pcStrBuf);

    return;
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏计算机视觉与深度学习基础

Leetcode 29 Divide Two Integers 位操作的巧妙运用

Divide two integers without using multiplication, division and mod operator. I...

26960
来自专栏python成长之路

集合常用操作

17640
来自专栏java一日一条

Python开发的10个小贴士

下面是十个Python中很有用的贴士和技巧。其中一些是初学这门语言常常会犯的错误。

8220
来自专栏章鱼的慢慢技术路

C语言中的循环语句练习

31160
来自专栏阿凯的Excel

Vlookup最高阶应用的全网唯一解决方案

古有烟笼寒水月笼沙的缥缈朦胧,今有查询函数的假模糊匹配的终极应用!今天分享的内容是全网唯一哦~ 为啥是假模糊匹配呢?一会和你说! 嗯嗯,Vlookup函数应该...

28750
来自专栏伪君子的梦呓

题解 ~ 输出三个数中的最大值 ~ C++ 做法

24350
来自专栏田云专栏

virtualdom diff算法实现分析

这两个月接触下vue ,花了两天时间了解了下vue的virtualdom实现,记录下学习心得。

37360
来自专栏Golang语言社区

map按key和按value排序

看一个题: 查找和排序 题目:输入任意(用户,成绩)序列,可以获得成绩从高到低或从低到高的排列,相同成绩 都按先录入排列在前的规则处理。 例示: jack 70...

38230
来自专栏C语言及其他语言

10个经典的C语言小程序

来源:codeceo 今天给大家分享10个比较基础的C语言的小程序,希望给C语言初学者带来一定帮助。 1、题目:有1、2、3、4个数字,能组成多少个互不相同且...

716130
来自专栏小文博客

小文’s blog–插入排序–《蓝桥杯代码笔记5》

17120

扫码关注云+社区

领取腾讯云代金券