字符串压缩与解码
1.字符串压缩
- 题目描述:
对字符串进行RLE压缩,将相邻的相同字符,用计数值和字符值来代替。例如:aaabccccccddeee,则可用3a1b6c2d3e来代替。
- 输入描述:
输入为a-z,A-Z的字符串,且字符串不为空,如aaabccccccddeee
- 输出描述:
压缩后的字符串,如3a1b6c2d3e。
-
解题思路:
遍历字符串,将字符串中的重复部分进行替换,将一个重复出现的字符子串替换成,某个字符重复出现的次数 + 该重复字符。
-
代码:
//字符串压缩
#include <iostream>
#include <string>
using namespace std;
string encode_string(string s){
string tmp = "";
string convert = "";
for(int i=0;i<s.size();i++){
int count = 1;
while(s[i]==s[i+1]){
i++;
count++;
}
convert = to_string (count);
tmp += convert;
tmp += s[i];
}
return tmp;
}
int main(){
string str;
cin >> str ;
cout << encode_string(str) << endl;
}
2.字符串解码
(1)leetcode 题目
-
题目描述:
给定一个经过编码的字符串,返回它解码后的字符串。编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 3a 或 2[4] 的输入。
-
代码:
//栈方法 #include <iostream> #include<istream> #include <string> #include<stack> #include<algorithm> using namespace std; string decodeString(string s){ stack<char> sta; int i = 0; while(i<s.size()){ if(s[i]!=']'){ sta.push(s[i]); }else{ string tmp = ""; while(sta.top()!='['){ tmp += sta.top(); sta.pop(); } reverse(tmp.begin(),tmp.end()); string str = tmp; sta.pop(); //pop '[' tmp = ""; while(!sta.empty()&&sta.top()>='0'&&sta.top()<='9'){ tmp += sta.top(); sta.pop(); } reverse(tmp.begin(),tmp.end()); int num = stoi(tmp); tmp = ""; while(num>0){ tmp += str; num--; } for(char& c:tmp){ sta.push(c); } } i++; } string res = ""; while(!sta.empty()){ res += sta.top(); sta.pop(); } reverse(res.begin(),res.end()); return res; } int main(){ string s; cin >> s; cout << decodeString(s) << endl; }
(2)腾讯面试算法题
-
题目描述:
小Q想要给他的朋友发送一个神秘字符串,但是他发现字符串的过于长了,于是小Q发明了一种压缩算法对字符串中重复的部分进行了压缩,对于字符串中连续的m个相同字符串S将会压缩为m|S,例如字符串ABCABCABC将会被压缩为[3|ABC],现在小Q的同学收到了小Q发送过来的字符串,你能帮助他进行解压缩么?
-
代码:
//栈方法
#include <iostream>
#include<istream>
#include <string>
#include<stack>
#include<algorithm>
using namespace std;
int main(){
string s;
cin >> s;
stack<char> sta;
int i = 0;
while(i<s.size()){
if(s[i]!=']'){
sta.push(s[i]);
}else{
//s[i]==']'
string tmp = "";
while(sta.top()!='|'){
tmp += sta.top();
sta.pop();
}
reverse(tmp.begin(),tmp.end());
string str = tmp;
//pop '|'
sta.pop();
tmp = "";
while(sta.top()!='['){
tmp += sta.top();
sta.pop();
}
reverse(tmp.begin(),tmp.end());
int num = stoi(tmp);
//pop '['
sta.pop();
tmp = "";
while(num>0){
tmp += str;
num--;
}
for(char& c:tmp){
sta.push(c);
}
}
i++;
}
string res="";
while(!sta.empty()){
res+=sta.top();
sta.pop();
}
reverse(res.begin(),res.end());
cout<<res<<endl;
return 0;
}
-
递归实现
#include <iostream> #include<istream> #include <string> using namespace std; string func(const string &s,int& i){ string res = ""; while(i<s.size()&&s[i]!=']'){ if(s[i]>='A'&&s[i]<='Z'){ res += s[i]; i++; }else{ //s[i]=='[' //index指向括号后的第一个数字 i++; //查找index后'|'首次出现的位置 int tmp = s.find('|',i); //返回从s字符串下标从i开始长度为tmp-i的字符串,并转换为整型 int num = stoi(s.substr(i,tmp-i)); i = tmp + 1; string str = func(s,i); i++; while(num>0){ res += str; num--; } } } return res; } int main(){ string ss = ""; int i=0; cin >> ss; cout << func(ss,i) << endl; }