一道很难的有关算法的测试题,写逆算法

 一道很难的有关算法的测试题,写逆算法

转载 来源:http://blog.liutaotao.com/blogview.asp?logID=38

最近在学习压缩算法,刚学懂了一个压缩算法,把它加以改造,做成了一道测试题.
这道题很难,这个算法很巧.如果不知道答案,我都没有把握能做出来.
如果你自信算法方面很强,可以试一试.如果你做不出来,又想知道答案,联系我.
以下已经给出了完整的 Decode 代码,Encode 代码有几处空,填入代码,使算法工作.

这个算法可以广泛地应用于注册机,网络传输等方面.


#include <Windows.h>
#include <stdio.h>

class CBitEncoder
{
  PBYTE m_pbuf;
  UINT m_len;

  UINT Prob;
  UINT _cacheSize;
  BYTE _cache;

  UINT64 Low;
  UINT uiSom;

  void WriteByte(BYTE b)  {      m_pbuf[m_len++] = b;  }
  void Init() 
  { 
    Prob = (1 << 10); 
    Low = 0;
    uiSom = 0xFFFFFFFF;
    _cacheSize = 0;
    _cache = 0;
  }
  void ShiftLow()
  {
    此处空13行代码;
  }
public:
  void SetOutputBufPtr(PBYTE buf)
  {
    Init();
    m_pbuf = buf;
    m_len = 0;
  }
  int GetLength()  {    return m_len;  }

  void FlushData()
  {
    此处空2行代码;
  }

  void bEncode(UINT symbol)
  {
    此处空17行代码;
  }
};
//---------------以上是 Encoder 以下是 Decoder

class CBitDecoder
{
  PBYTE m_psrc;
  int m_srclen;

  UINT uiSom;
  UINT uiAny;
  UINT Prob;

  BYTE ReadByte()
  {
    m_srclen--;
    return *m_psrc++;
  }
  void Init()
  {
    Prob = (1 << 10);
    uiAny = 0;
    uiSom = 0xFFFFFFFF;
    for(int i = 0; i < 4; i++)
      uiAny = (uiAny << 8) | this->ReadByte();
  }
public:
  void SetSrcBuf(PBYTE psrc, int srclen)
  {
    m_psrc = psrc;
    m_srclen = srclen;
    Init();
  }
  int GetRemainByte()  {    return m_srclen;  }
  
  bool bDecode() 
  {
    bool b;
    UINT u = (this->uiSom >> 11) * this->Prob;
    if (this->uiAny < u)
    {
      this->uiSom = u;
      this->Prob += ((1 << 11) - this->Prob) >> 5;
      b = false;
    }
    else
    {
      this->uiSom -= u;
      this->uiAny -= u;
      this->Prob -= (this->Prob) >> 5;
      b = true;
    }
    if (this->uiSom < (1 << 24))
    {
      this->uiAny = (this->uiAny << 8) | this->ReadByte();
      this->uiSom <<= 8;
    }
    return b;
  }
};

int Test_Encode(PBYTE psrc, int srclen, PBYTE buf)

  CBitEncoder bitEncoder;
  bitEncoder.SetOutputBufPtr(buf);

  for (int i=0;i<srclen;i++)
  {
    BYTE b = psrc[i];
    for (int j=0;j<8;j++)
    {
      bitEncoder.bEncode((b>>j) & 1);
    }
  }
  bitEncoder.FlushData();

  return bitEncoder.GetLength();
}

int Test_Decode(PBYTE psrc, int srclen, PBYTE buf)
{
  CBitDecoder bitDecoder;
  bitDecoder.SetSrcBuf(psrc, srclen);

  int totallen = 0;
  for (;;)
  {
    BYTE b = 0;
    for (int i=0;i<8;i++)
    {
      b += (bitDecoder.bDecode() << i);
      if (bitDecoder.GetRemainByte() < 0)
        return totallen;
    }
    *buf++ = b;
    totallen++;
  }
  return totallen;
}

void main()
{
  char* psrc = "exam by LiuTaoTao 20070728";
  int srclen = strlen(psrc);
  BYTE buf[3000];
  int len = Test_Encode((PBYTE)psrc, srclen, buf);
  printf("Srclen = %d Encode len = %d /n", srclen, len);

  BYTE outbuf[3000];
  int len2 = Test_Decode(buf, len, outbuf);
  printf("Decode len from %d to %d /n", len, len2);
  if (len2 >= srclen && !memcmp(psrc, outbuf, srclen))  
    printf("OK/n");  
  else
    printf("Error/n");
}
// 这种压缩算法,代码简单,速度快
// 还有一个缺点,就是不能很有效地判断是否已经解码结束,有时候会多解几个字节出来

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值