26個字母壓縮編碼

2022-04-11 10:26:48 字數 4141 閱讀 5311

一 位元組壓縮

實現原理:因為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 關懷 親人出門時送上外套,回來時遞杯熱茶,生病時多謝些安慰。這會讓親人覺得他是你生命中最重要的人...