題目
文本壓縮有很多種方法,這里我們只考慮最簡(jiǎn)單的一種:把由相同字符組成的一個(gè)連續(xù)的片段用這個(gè)字符和片段中含有這個(gè)字符的個(gè)數(shù)來(lái)表示。例如
ccccc就用5c來(lái)表示。如果字符沒(méi)有重復(fù),就原樣輸出。例如aba壓縮后仍然是aba。
解壓方法就是反過(guò)來(lái),把形如
5c這樣的表示恢復(fù)為ccccc。
本題需要你根據(jù)壓縮或解壓的要求,對(duì)給定字符串進(jìn)行處理。這里我們簡(jiǎn)單地假設(shè)原始字符串是完全由英文字母和空格組成的非空字符串。
輸入格式:
輸入第一行給出一個(gè)字符,如果是
C就表示下面的字符串需要被壓縮;如果是D就表示下面的字符串需要被解壓。第二行給出需要被壓縮或解壓的不超過(guò) 1000 個(gè)字符的字符串,以回車(chē)結(jié)尾。題目保證字符重復(fù)個(gè)數(shù)在整型范圍內(nèi),且輸出文件不超過(guò) 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
通過(guò)代碼(極致壓行版)
#include <iostream>
#include <ctype.h>
using namespace std;
void Cprint(int& count, char a) {//注意count是引用變量
if (count != 1) cout << count;
cout << a;
count = 0;
}
int main () {
string str, c;
int i = 0, count = 1;//i是解碼的循環(huán)變量,控制下標(biāo)。count是壓縮過(guò)程中記錄重復(fù)字符出現(xiàn)次數(shù)的
getline(cin, c); getline(cin, str);//輸入
if (c == "C") {
for (int j = 1; j < str.length(); j++, count++)//每次循環(huán)count++
if (str[j - 1] != str[j]) Cprint(count, str[j - 1]);//如果遇到一個(gè)字符和前一個(gè)不一樣,輸出,讓count歸零
Cprint(count, str[str.length() - 1]);//輸出最末尾的一個(gè)或一串
} else if (c == "D") {
if (!isdigit(str[i])) cout << str[i++];//第一個(gè)不是數(shù)字,直接輸出,i++訪(fǎng)問(wèn)下一個(gè)字符
for (int n = 0; i < str.length(); n = 0, i++) {//n為每個(gè)字符前的數(shù)字
for (; i < str.length() && isdigit(str[i]); n *= 10, n += (str[i++] - '0'));//如果是數(shù)字,就把數(shù)字字符轉(zhuǎn)換成數(shù),這里不是雙層for循環(huán)嵌套,這個(gè)for循環(huán)后有一個(gè)分號(hào)
for (int j = 0; j < (n == 0 ? 1 : n); j++) cout << str[i];//循環(huán)輸出字符,如果沒(méi)有遇到數(shù)字,n為0,就輸出一次
}
}
return 0;
}
通過(guò)代碼
#include <iostream>
#include <algorithm>
#include <ctype.h>
using namespace std;
struct out { char c; int n; };
void C () {
string str;
getline(cin, str);
int n = str.length();
out data[n] = {0};
char last = -1;
int count = -1;
for (int i = 0; i < n; i++) {
if (str[i] != last)
data[++count].c = str[i];
data[count].n++;
last = str[i];
}
for (int i = 0; i < count + 1; i++) {
if (data[i].n != 1)
cout << data[i].n;
cout << data[i].c;
}
}
void D () {
string str;
getline(cin, str);
int i = 0;
if (!isdigit(str[i]))
cout << str[i++];
while (i < str.length()) {
int n = 0;
while (i < str.length() && isdigit(str[i])) {
n *= 10;
n += str[i++] - '0';
}
for (int j = 0; j < n; j++)
cout << str[i];
i++;
while ( i < str.length() && !isdigit(str[i]))
cout << str[i++];
}
}
int main () {
char c;
scanf("%c%*c", &c);
if (c == 'C') C();
else D();
return 0;
}
思路與注意
coding(壓縮)一個(gè)函數(shù),decoding(解壓)一個(gè)函數(shù)分別處理
兩個(gè)函數(shù)統(tǒng)一使用getline,main函數(shù)里面要吃掉第一行的換行符
-
對(duì)于coding過(guò)程
定義一個(gè)結(jié)構(gòu)體數(shù)組,儲(chǔ)存字符與個(gè)數(shù)。數(shù)組長(zhǎng)度為輸入string的長(zhǎng)度(如果輸入的string不能壓縮,正好夠用)
遍歷一遍string,如果字符和前一個(gè)字符一樣,那么當(dāng)前結(jié)構(gòu)體(變量)的字符個(gè)數(shù)++,一旦改變,存到下一個(gè)結(jié)構(gòu)體中。
輸出結(jié)構(gòu)體,先輸出個(gè)數(shù)(大于1才輸出),再輸出這個(gè)字符
-
對(duì)于decoding過(guò)程
先判斷第一個(gè)字符,如果是字母直接輸出這個(gè)字母,然后字符串的“指針”向后移。
進(jìn)入循環(huán),循環(huán)的操作為,得到數(shù)字,輸出數(shù)字后的字母,然后輸出后面的單個(gè)字母,直到遇到下一個(gè)數(shù)字,進(jìn)入下一次循環(huán),或者遇到字符串結(jié)束,那就結(jié)束。
注意不要用isalpha()函數(shù)(考慮空格的存在)
反思與評(píng)價(jià)
- 嗯