1

 
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
public class UserSolution {
    private static final int FRAMESIZE = 256;
 
    private static int num;
    private static int max;
    private static char[][] frames;
    private static int[] lookingTable;
 
    public void Init(int N, int[] size, char[] data, int M, Solution.Huffman[] code) {
        frames = new char[N][FRAMESIZE];
        max = N;
 
        int len = 0;
        for (int i = 0; i < M; i++)
            if (code[i].codewordLength > len) len = code[i].codewordLength;
        int mask = 0xFFFFFF >> (24 - len);  //用于后面更新tmpCode
         
        lookingTable = new int[1 << len];  //查找表,存储tmpCode对应的code数组索引
        for (int i = 0; i < M; i++)
            for (int j = 0; j < 1 << (len - code[i].codewordLength); j++) //长度为codewordLength的code,需要初始化2^(len-code[i].codewordLength)个位置
                lookingTable[code[i].codeword << (len - code[i].codewordLength) | j] = i;
 
        int baseIdx = 0;
        for (int i = 0; i < N/16; i++) {
            int bitIdx = 0;
            int frameCharIdx = 0;
            int codeLen = 0;
            int tmpCode = 0;
            while (frameCharIdx < 4096) {
                if (bitIdx == 32768) {  //由于使用固定长度的tmpCode,因此需要处理最后bit的边界情况
                    tmpCode = tmpCode << (len - codeLen);
                    codeLen = len;
                }
                while (codeLen < len) {  //每次读入len位数据,判断其对应的code
                    int diff = len - codeLen;
                    if (8 - bitIdx%8 >= diff) {  //当前data剩余位数足够
                        tmpCode = tmpCode << diff | (data[baseIdx + (bitIdx>>3)] << (bitIdx%8) >> (8 - diff));  //取对应位,更新tmpCode
                        bitIdx += diff;
                        codeLen = len;
                    } else //当前data剩余位数不够
                        int rest = 8 - bitIdx%8;
                        tmpCode = tmpCode << rest | (data[baseIdx + (bitIdx>>3)] & 0xFF >> (bitIdx%8)); //取对应位,更新tmpCode
                        bitIdx += rest;
                        codeLen += rest;
                    }
                }
                //此时tmpCode必然对应一个明文,更新到frames中
                frames[(i<<4) + frameCharIdx/FRAMESIZE][frameCharIdx%FRAMESIZE] = (char)code[lookingTable[tmpCode]].symbol;
                frameCharIdx++;
                codeLen -= code[lookingTable[tmpCode]].codewordLength;  //减去上一个char对应的有效位数
                tmpCode = tmpCode & (mask >> code[lookingTable[tmpCode]].codewordLength);  //去除上一个char对应的有效位后,剩余的tmpCode
            }  
            baseIdx += size[i];
        }
        //从D frames反推O frames,注意每16个frame为一个block
        for (int i = 0; i < N/16; i++)
            for (int k = 1; k < 16; k++)
                for (int j = 0; j < FRAMESIZE; j++)
                    frames[(i<<4) + k][j] = (char)(frames[(i<<4) + k][j] + frames[(i<<4) + k - 1][j] - 128);
    }
 
    public void Goto(int frame) {
        num = frame;
    }
 
    public int Tick(char[] screen) {
        if (num < max) num++;
        for (int i = 0; i < FRAMESIZE; i++)
            screen[i] = frames[num - 1][i];
        return num - 1;
    }
}
原文地址:https://www.cnblogs.com/mhc-fly/p/8556023.html