天天看點

[算法題] 位元組流解析

位元組流解析

題目标題:

  • 根據數值占用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;
}      

繼續閱讀