[算法题] 字节流解析

字节流解析

题目标题:

  • 根据数值占用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 条评论
登录 后参与评论

相关文章

来自专栏个人分享

JAVA源码走读(二)二分查找与Arrays类

对数组排序:通过sort方法,按升序。 比较数组:通过equals方法比较数组中元素值是否相等。 查找数组元素:通过binarySearch方法能对排序好的数组...

984
来自专栏Golang语言社区

第七节 Go语言运算符

干货来了!!!为了让更多的小伙伴喜欢Golang、加入Golang之中来,Golang语言社区发起人彬哥联合业界大牛共同推出了Go语言基础、进阶、提高课程,目前...

1013
来自专栏恰同学骚年

剑指Offer面试题:3.替换空格

  在网络编程中,如果URL参数中含有特殊字符,如空格、'#'等,可能导致服务器端无法获得正确的参数值。我们需要将这些特殊符号转换成服务器可以识别的字符。转换的...

592
来自专栏云霄雨霁

子字符串查找----Rabin-Karp算法(基于散列)

1310
来自专栏尾尾部落

[LeetCode]Degree of an Array 数组的度 [LeetCode]Degree of an Array 数组的度

链接:https://leetcode.com/problems/degree-of-an-array/description/ 难度:Easy 题目:69...

852
来自专栏九彩拼盘的叨叨叨

你可能不知道的jQuery工具方法

将array-like的对象转化成数组。 array-like的对象有length属性,但没有数组的方法,也不能被for-in来遍历。 常见的array-l...

441
来自专栏程序员互动联盟

【编程基础】C语言类型转换

我们在编程序的时候,经常会出现不同类型的数据之间需要计算、赋值,必然会出现类型转换问题。C语言的变量数据类型是可以转换的,转换的方法有两类,一种是自动转换,一种...

35813
来自专栏闻道于事

Java之数组

数组概述 数组是具有相同数据类型的一组数据的集合。数组中的每个元素具有相同的数据类型。数组的长度是固定的。在Java中同样将数组看作是一个对象,虽然基本数据类型...

2896
来自专栏技术小站

c++(三)

函数在调用之前必须进行声明或者定义,函数的声明:返回值类型 函数名(参数类型 参数名称.......);其中参数名称可以省略;

873
来自专栏韦弦的微信小程序

Swift 字符串转整数 (atoi) - LeetCode

1、在找到第一个非空字符之前,需要移除掉字符串中的空格字符。如果第一个非空字符是正号或负号,选取该符号,并将其与后面尽可能多的连续的数字组合起来,这部分字符即为...

863

扫码关注云+社区