一 位元組壓縮
實現原理:因為a~z的ascii碼用不了乙個位元組表示,減小『a』後每個字元實際上代表了0-26,五個bit即可表示,壓縮後,能省
3/8的空間, 關鍵在於如何組織儲存順序便於檢索和儲存,同時要考慮儲存的時間效率
如果將五位按照順序依次儲存,一不好儲存,二不好訪問
訪問按照位元組進行,應盡量將 m個陣列合成n個位元組,能否將8
個字元存成
5個位元組呢?
因此考慮就5位再拆下,分解成最高位和低四位,這樣每兩個字元就可以轉換成乙個新的數了;每
8個字元的最高位可組合成乙個位元組 ;4、8的規律性很強,組合分解都很方便
××××××××××××××××××××××××××××××××
#define lowmask 0x0f
#define highmask (1<<4)
#define charlen 7
輸入引數:inarray 待編碼的字元陣列;inlen陣列的長度
輸入引數:outarray 編碼後的字元陣列;outlen編碼後陣列的長度
// unsigned char outarray 編碼後的字元陣列用到了最高位,是有效位,非符號位
voidcodechar(const char inarray,unsigned int inlen, unsigned char outarray[ ], unsigned int &outlen)
inindex++;
}if(inindex%2 == 1) //
某個輸出字元只用了高四位,但儲存合成值的輸出下標未增加
outindex++;
if(compoudindex != 0) //
此時說明輸入陣列個數非
8的倍數,最後乙個合成值上面未儲存
outlen =outindex; //
儲存轉換完畢後的輸出陣列長度
}// 輸入引數:inarray 上面編碼後的陣列;inlen編碼後的陣列長度;outk待解碼字元在原陣列中的下標位置
// 輸出引數:outchar解碼的碼值;inlen編碼後的陣列長度
voiddecodechar(const unsigned char inarray,unsigned int inlen, unsigned int outk, char &outchar)
if(outk%2 == 0) // 偶數儲存在高位
lowvalue = inarray[outk/2+outk/8 ] >> 4;
else
lowvalue = inarray[outk/2+outk/8] & lowmask;
compoudvalue = highvalue | lowvalue; // 解碼後的數字
compoudvalue += 'a'; // 解碼後的字元
outchar = compoudvalue;
} voidmain(void)
;int outindex = 0;
unsigned int outcount;
int incount = strlen(in);
float coderatio = 0;
char outchar;
while(outindex < 100)
out[outindex++] = 0;
codechar(in,incount, out, outcount);
out[incount] = '/0'; // 編碼
cout<
printf("%s",out);
coderatio = (float )outcount/incount;
printf("%6f",coderatio);
outindex = 0; // 解碼
while(outindex < incount)
}××××××××××××××××××××××××××××××××
××××××××××××××××××××××××××××××××
二 26進製編碼
26個字母就當作
26進製 ,然後每6個字母轉換為乙個long,32位的 4 個位元組.. 壓縮
1/3
0-26個當作26進製對應的26個數符,把
6個字元組成的字串當作乙個
26進製的數 .,轉換為10進製整數,剛好範圍可以被32
位long
容納 ,不過存在一點點浪費.
比如a代表1,b代表2 ,ab代表26進製的12, 即十進位制的28;
反過來從long x得到原始的字元
x/26^5
即得到六個字元的高位,依次類推;但對於最後乙個整型數應該特殊考慮。
就相當於十六進展和十進位制的轉換問題
××××××××××××××××××××××××××××××××
#define azmax 26
//輸入引數:inarray 待編碼的字元陣列;inlen陣列的長度
//輸入引數:outarray 編碼後的整型陣列; outlen編碼後陣列的長度
// unsigned int outarray 編碼後的整型陣列用到了最高位,是有效位,非符號位
void azcodechar(const char inarray,unsigned int inlen, unsigned int outarray, unsigned int &outlen)
}if(inindex%6 != 0) //
不足六個字元,上面未儲存
outlen =outindex; // 儲存轉換完畢後的輸出陣列長度
}// 輸入引數:inarray 上面編碼後的陣列;inlen編碼後的陣列長度;outindex待解碼字元在原陣列中的下標位置;outlen
待解碼字元的原陣列總長度(比按
5位編碼多了乙個引數)
// 輸出引數:outchar解碼的碼值
voidazdecodechar(const unsigned int inarray,unsigned int inlen, unsigned int outindex, unsigned int outlen, char &outchar)
else // 待解碼字元在最後乙個合成值內
while(devideindex > 0)
decodevalue = (inarray[outindex/6]/devidevalue)%azmax; //
得到當前的個位數
outchar = decodevalue + 'a';
} voidmain(void)
;int outindex = 0;
unsigned int outcount;
int incount = strlen(in);
float coderatio = 0;
char outchar;
while(outindex < 100)
out[outindex++] = 0;
azcodechar(in,incount, out, outcount);
cout<
coderatio = (float)outcount * sizeof(int) /incount;
printf("%6f/n",coderatio);
outindex = 0; // 解碼
while(outindex < incount)
}××××××××××××××××××××××××××××××××
××××××××××××××××××××××××××××××××
細心的讀者可能會發現,上述將字串看成26進製的字串,然後再將其編碼為十進位制,即int型別存起來;
而對於「12356819 」型別的十進位制的字串轉化為十進位制的 int數,不就是常考的atio(char *in)
函式麼? 考慮過「011000010100」二進位制的字串麼?八進位制「 23104762 」呢?
相信這個時候你應該明白了26進製字串「adkjflmgdsjkflkmgzxy」的儲存轉換原理了吧
而其解碼過程不就是
itoa(int k, char *out)
函式 麼?
有興趣的朋友可以參考前面的帖子「從
「整數轉換成字串
」看演算法的聯想
」
音訊壓縮編碼
只有當信源產生的訊號具有冗餘時,才能對其進行壓縮。下面介紹幾種音訊冗餘的概念 1 時域冗餘度 幅度的非均勻分布 統計表明,語音中的小幅度樣本比大幅度樣本出現的概率要高。週期之間的相關 在特定的瞬間,某一聲音往往只是有頻帶內少數頻率成分起作用。當聲音中只存在少數幾個頻率時,就會象波一樣,在週期與週期之...
RLE 壓縮編碼
rle全程run length encoding,翻譯為遊程編碼,又譯行程長度編碼,又稱變動長度編碼法 run coding 在控制論中對於二值影象而言是一種編碼方法,對連續的黑 白畫素數 遊程 以不同的碼字進行編碼。遊程編碼是一種簡單的非破壞性資料壓縮法,其好處是加壓縮和解壓縮都非常快。其方法是計...
26個字母的幸福
admire 讚美 好話 人人都愛聽,最好的話當然留給最親的人。親人給你做的飯,買的漂亮衣服 都值得誇讚。believe 信任 相信親人對你的好,親戚的真誠,朋友的友好 別讓猜忌破壞幸福。concern 關懷 親人出門時送上外套,回來時遞杯熱茶,生病時多謝些安慰。這會讓親人覺得他是你生命中最重要的人...