我的PAT系列文章更新重心已移至Github,歡迎來看PAT題解的小伙伴請到Github Pages瀏覽最新內(nèi)容。此處文章目前已更新至與Github Pages同步。歡迎star我的repo。
題目
文本壓縮有很多種方法,這里我們只考慮最簡單的一種:把由相同字符組成的一個連續(xù)的片段用這個字符和片段中含有這個字符的個數(shù)來表示。例如 ccccc 就用
5c 來表示。如果字符沒有重復(fù),就原樣輸出。例如 aba 壓縮后仍然是 aba。
解壓方法就是反過來,把形如 5c 這樣的表示恢復(fù)為 ccccc。
本題需要你根據(jù)壓縮或解壓的要求,對給定字符串進(jìn)行處理。這里我們簡單地假設(shè)原始字符串是完全由英文字母和空格組成的非空字符串。
輸入格式:
輸入第一行給出一個字符,如果是 C 就表示下面的字符串需要被壓縮;如果是 D 就表示下面的字符串需要被解壓。第二行給出需要被壓縮或解壓的不超過
1000 個字符的字符串,以回車結(jié)尾。題目保證字符重復(fù)個數(shù)在整型范圍內(nèi),且輸出文件不超過 1MB。
輸出格式:
根據(jù)要求壓縮或解壓字符串,并在一行中輸出結(jié)果。
輸入樣例 1:
C
TTTTThhiiiis isssss a tesssst CAaaa as
輸出樣例 1:
5T2h4is i5s a3 te4st CA3a as
輸入樣例 2:
D
5T2h4is i5s a3 te4st CA3a as10Z
輸出樣例 2:
TTTTThhiiiis isssss a tesssst CAaaa asZZZZZZZZZZ
思路
也不是很難,壓縮和解壓是獨立的,我寫了兩個函數(shù)
- compress:壓縮。記錄當(dāng)前字符和前一個字符,不一樣時就說明需要總結(jié)前一個字符的出現(xiàn)次數(shù),并且輸出。在我的實現(xiàn)里,借用最后的換行符為最后一個字符,就無須處理末尾的特殊情況。
- decompress:解壓。同樣用一個計數(shù)變量記錄需要輸出的次數(shù),由于我采用的是逐一讀取字符的方法,所以如果次數(shù)大于10就要注意把多位數(shù)加在一起(如題目中10Z)。遇到數(shù)字就改變計數(shù)變量,遇到其他字符就輸出。
代碼
最新代碼@github,歡迎交流
#include <stdio.h>
void compress()
{
char previous = getchar(), current;
int count = 1;
while((current = getchar()))
{
if(current == previous)
{
count++; /* Increament count */
}
else
{
if(count > 1) /* Only print if count > 1 */
printf("%d", count);
putchar(previous);
previous = current;
count = 1;
}
if(current == '\n') /* Don't put this in while() */
break;
}
}
void decompress()
{
char c;
int count = 0;
while((c = getchar()) != '\n')
{
if(c >= '0' && c <= '9') /* If it is number */
{
count = count * 10 + c - '0'; /* Accumulate count */
}
else /* If it is not number */
{
if(count == 0) /* No number before char */
count = 1; /* print once */
for(int i = 0; i < count; i++) /* Or print 'count' times */
putchar(c);
count = 0; /* Reset 'count' */
}
}
}
int main()
{
switch(getchar())
{
case 'C':
while(getchar() != '\n');
compress();
break;
case 'D':
while(getchar() != '\n');
decompress();
break;
default:
break;
}
return 0;
}