算法竞赛入门经典(第二版) | 例题4-4 信息解码 (紫皮书牛啤!)(UVa213,Message Decoding)
大意:
二進(jìn)制編碼中取前三位,得到編碼長(zhǎng)度為n(0<=n<=7), 按此長(zhǎng)度重復(fù)截取編碼中剩余部分(n位一截),直到讀取n個(gè)1結(jié)束。再次取三位,長(zhǎng)度為n,重復(fù)上述操作…直至n個(gè)1后接000,文本結(jié)束。
本題輸出格式:若用回車(chē)分割出多行編碼, 則編一行,輸出一行。(注意英文原題)
題目(提交)鏈接→UVa-213
百度翻譯→百度翻譯
沒(méi)使用過(guò)該網(wǎng)站的同學(xué)請(qǐng)猛戳這里→vJudge教程
分析:
1、循環(huán)1:用readcodes()函數(shù)讀取編碼字符,存入二維數(shù)組,二維數(shù)組橫坐標(biāo)為二進(jìn)制位數(shù),一位存第一行,二位存第二行… 形成表格。輸入EOF則退出。
2、循環(huán)2:用readint()函數(shù)獲取編碼長(zhǎng)度,若長(zhǎng)度為0則退出,不為0則進(jìn)入循環(huán)2
3、循環(huán)3:用readint()函數(shù)按長(zhǎng)度截取編碼,期間用readchar()函數(shù)跳過(guò)回車(chē)符,同時(shí)readint()函數(shù)將該二進(jìn)制數(shù)轉(zhuǎn)化為十進(jìn)制,
查表,輸出對(duì)應(yīng)的字符,直至讀出n個(gè)1,返回循環(huán)1,重復(fù)…
還不是很明白的同學(xué)。把代碼中三段注釋消除,將所有函數(shù)的頭部標(biāo)紅,自己調(diào)試一遍就明白了。
代碼:
#include <iostream> #include <cstdio> #include <cstring> using namespace std;int readchar() { //處理編碼文本可以由多行組成的情況,"跨行讀字符",單獨(dú)開(kāi)辟函數(shù)。 for(;;) {int ch = getchar();if(ch != '\n' && ch != '\r') return ch; //一直讀到非換行符為止。 } } int readint(int c) { //獲取頭部三位編碼,并轉(zhuǎn)化為十進(jìn)制。 int v = 0;while(c--) v = v * 2 + readchar() - '0'; //二進(jìn)制轉(zhuǎn)十進(jìn)制核心代碼。 return v; } int code[8][1<<8]; //將字符寫(xiě)入這里 int readcodes() { //將所有字母按其二進(jìn)制編碼順序存入code ,第一行存一位、二行存3(1<<len-1)位.. memset(code, 0, sizeof(code)); //清空數(shù)組(二維數(shù)組也可同樣清空) code[1][0] = readchar(); //直接調(diào)到下一行讀取,因?yàn)檫@一行只能有一個(gè)二進(jìn)制數(shù)0(1表示結(jié)束) for(int len = 2; len <= 7; len++) {for(int i = 0; i < (1<<len)-1; i++) {int ch = getchar();if(ch == EOF) return 0;if(ch == '\n' || ch == '\r') return 1;code[len][i] = ch;}} return 1; } void printcodes() {for(int len = 1; len <= 7; len++) for(int i = 0; i < (1<<len)-1; i++) {if(code[len][i] == 0 ) return;printf("code[%d][%d] = %c\n", len, i, code[len][i]);} } int main() { while(readcodes()) { //無(wú)法讀取更多編碼頭時(shí)退出 // printcodes();for(;;) {int len = readint(3); //獲取接下來(lái)的編碼長(zhǎng)度 if(len == 0) break; //如果為0,文本輸入結(jié)束 // printf("len=%d\n", len);for(;;) {int v = readint(len); //按長(zhǎng)度決定取幾位 // printf("v=%d\n", v);if(v == (1 << len)-1) break; //如果v等于全為1的二進(jìn)制數(shù),則表示結(jié)束。 putchar(code[len][v]);}} putchar('\n');}return 0; }收獲:
1、\r是回車(chē)符,其中r是return的縮寫(xiě)。回車(chē)符的作用是將當(dāng)前位置移到本行的開(kāi)頭。
2、二維數(shù)組的清空方法。
3、將所有函數(shù)的頭部都標(biāo)紅,就可以在調(diào)試時(shí)進(jìn)入(調(diào)試技巧)。
4、二進(jìn)制的表示方法。注意: 一定是(1<<len)-1; 1<<len-1等價(jià)于1<<(len-1)
5、進(jìn)制之間轉(zhuǎn)化函數(shù)(將文中2換成x。)
6、文件結(jié)束的判斷;‘000’結(jié)束的判斷;‘1’結(jié)束的判斷;三步層層遞進(jìn)
7、紫皮書(shū)牛啤!我為紫皮書(shū)帶鹽!不接受反駁!
最后,分享一條大牛的建議(對(duì)筆者受益匪淺):平時(shí)在做題的時(shí)候,一定要尋找最優(yōu)解,而不是 ac 了就不管了,應(yīng)該多看看別人的解法。
超強(qiáng)干貨來(lái)襲 云風(fēng)專(zhuān)訪(fǎng):近40年碼齡,通宵達(dá)旦的技術(shù)人生總結(jié)
以上是生活随笔為你收集整理的算法竞赛入门经典(第二版) | 例题4-4 信息解码 (紫皮书牛啤!)(UVa213,Message Decoding)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 算法竞赛入门经典(第二版) | 例题4-
- 下一篇: 算法竞赛入门经典(第二版) | 例题4-