题目描述:
一个字符串,如果连续三个都是同一个字母的话,它们将会被消去。
每次只能消去相邻的相同的三个字母。例如aaaabbbc,消去后变成ac。
有些特殊的字符串,消去一次之后还可以再次消去。
例如abbbaa:第一次消去了中间的bbb,变成了aaa,第二次消去aaa,字符串变成空字符串。
现在给你一个长度不超过100的字符串,请你不断地对这个字符串进行消去,直到不能消去为止。
输入格式:
一行,长度不超过100的字符串。
输出格式:
第一行,输出最终剩下的字符串的长度。
第二行,输出最终的字符串
输入样例:
aaaabbbc
输出样例:
2
ac
我的题解:
本题用到栈的知识,将字符一个一个压入栈中,当要进栈的元素和当前栈顶的元素以及栈顶的前一个元素三者均相同时,达到消除条件,此时弹出栈顶元素和栈顶的前一个元素,若不再满足消除条件,则元素进栈。最后记得将最后的栈中元素存入字符串时要翻转字符串,因为栈是先进后出的。
#include<iostream>
#include<stack>
#include<algorithm>
using namespace std;
string myDelete(string S)
{
stack<char> st;
int sLen = S.length();
for( int i = 0; i < sLen; i++)
{
if(st.size() >= 2)
{
//获取栈顶和栈顶前一个元素的值
int element1 = st.top();
st.pop();
int element2 = st.top();
st.push(element1);
if (S[i] == element1 && S[i] == element2)// 可以消除的情况
{
st.pop();
st.pop();
}
else // 无法消除 压入栈
{
st.push(S[i]);
}
}
else // 无法消除 压入栈
{
st.push(S[i]);
}
}
// 将栈中元素放到ans字符串
string ans = "";
while (!st.empty())
{
ans += st.top();
st.pop();
}
reverse (ans.begin(), ans.end()); // 此时字符串需要反转一下
return ans;
}
int main()
{
string A;
cin >> A;
string B = myDelete(A);
cout << B.length() << endl;
for(int i = 0;i < B.length();i++)
{
cout << B[i];
}
return 0;
}