问题描述
给出一个包含重复字符和突发长度的字符串,输出该字符串,以使字符串中相同相邻字符的数量小于突发长度。
输入:abbccccdd,burstLen = 3
正确的输出:abbdd
我的输出:abbd
输入:abbcccdeaffff,burstLen = 3
正确的输出:abbdea
我的输出:修道院
//Radhe krishna ki jytoi alokik
#include <bits/stdc++.h>
using namespace std;
string solve(string s,int burstLen)
{
stack<pair<char,int>> ms;
for (int i = 0; i < s.size(); i++)
{
if (!ms.empty() && ms.top().first == s[i])
{
int count = ms.top().second;
ms.push({s[i],count + 1});
}
else
{
if(ms.empty() == true || ms.top().first != s[i])
{
if(!ms.empty() && ms.top().second >= burstLen)
{
int count = ms.top().second;
while(!ms.empty() && count--)
ms.pop();
//(UPDATE)
ms.push({s[i],1});
}
else
ms.push({s[i],1});
}
}
}
if(!ms.empty() and ms.top().second >= burstLen)
{
int count = ms.top().second;
while(!ms.empty() && count--)
ms.pop();
}
string ans = "";
while (!ms.empty())
{
ans += ms.top().first;
ms.pop();
}
reverse(ans.begin(),ans.end());
return ans;
}
int main()
{
string s;
int burstLen;
cin >> s;
cin >> burstLen;
cout << solve(s,burstLen) << "\n";
}
解决方法
我尝试了一下,但是看起来很复杂,所以我建议使用标准库中的一些函数来简化函数。
示例:
#include <algorithm>
#include <iostream>
#include <initializer_list>
#include <iterator>
std::string solve(const std::string& in,size_t burstlen) {
std::string retval;
for(std::string::const_iterator begin = in.cbegin(),bend;
begin != in.end();
begin = bend)
{
// find the first char not equal to the current char
bend = std::find_if_not(std::next(begin),in.end(),[curr=*begin](char ch){ return ch==curr; });
if(std::distance(begin,bend) < burstlen) {
// length ok,append it
retval.append(begin,bend);
}
}
return retval;
}
int main() {
std::initializer_list<std::string> tests{
"abbccccdd","abbcccdeaffff"};
for(auto test : tests) std::cout << solve(test,3) << '\n';
}
输出:
abbdd
abbdea
,
至少最好使用容器适配器std::queue
而不是std::stack
,因为不需要调用算法std::reverse
。
此外,如果堆栈中的项目包含第二个存储频率的数据成员,那么您只需增加此数据成员的重复字符即可,而不是将每个重复的字符放在堆栈中。
例如您程序中的此代码段
if (!ms.empty() && ms.top().first == s[i])
{
int count = ms.top().second;
ms.push({s[i],count + 1});
}
使函数定义过于复杂和不清楚,因为相同的字符以不同的频率被压入堆栈。
但是,如果要使用容器适配器std :: stack,则函数定义可能看起来更简单。您没有使用std::string
类的功能。
这里是一个演示程序,展示了如何使用您的方法std::stack
来编写函数。
#include <iostream>
#include <string>
#include <utility>
#include <stack>
#include <iterator>
#include <algorithm>
std::string solve( const std::string &s,size_t burstLen )
{
std::stack<std::pair<char,size_t>> stack;
for ( const auto &c : s )
{
if ( stack.empty() || stack.top().first != c )
{
stack.push( { c,1 } );
}
else
{
++stack.top().second;
}
}
std::string ans;
while ( !stack.empty() )
{
if ( stack.top().second < burstLen )
{
ans.append( stack.top().second,stack.top().first );
}
stack.pop();
}
std::reverse( std::begin( ans ),std::end( ans ) );
return ans;
}
int main()
{
std::cout << solve( "abbccccdd",3 ) << '\n';
std::cout << solve( "abbcccdeaffff",3 ) << '\n';
}
程序输出为
abbdd
abbdea
在删除一个不小于突发长度的字符序列后,从堆栈的左侧和右侧子序列中得到一个新的序列,该序列又一次不小于突发长度,并且还需要删除它。
在这种情况下,您可以使用两个堆栈。
这是一个演示程序。
#include <iostream>
#include <string>
#include <utility>
#include <stack>
#include <iterator>
#include <algorithm>
std::string solve( const std::string &s,size_t>> stack_in;
for ( const auto &c : s )
{
if ( stack_in.empty() || stack_in.top().first != c )
{
stack_in.push( { c,1 } );
}
else
{
++stack_in.top().second;
}
}
std::stack<std::pair<char,size_t>> stack_out;
while ( !stack_in.empty() )
{
if ( !stack_out.empty() && stack_out.top().first == stack_in.top().first )
{
if ( stack_out.top().second + stack_in.top().second < burstLen )
{
stack_out.top().second += stack_in.top().second;
}
else
{
stack_out.pop();
}
}
else if ( stack_in.top().second < burstLen )
{
stack_out.push( stack_in.top() );
}
stack_in.pop();
}
std::string ans;
while ( !stack_out.empty() )
{
ans.append( stack_out.top().second,stack_out.top().first );
stack_out.pop();
}
return ans;
}
int main()
{
std::cout << solve( "abbccccdd",3 ) << '\n';
std::cout << solve( "aabcddeeedccbaa",3 );
}
程序输出为
abbdd
abbdea
aabbaa
,
我的解决方法:
创建一个由字符和字符数组成的成对堆栈
如果堆栈为空或堆栈的顶部元素与字符串中的当前元素不相等
情况1:如果堆栈顶部元素的频率大于或等于k,则将其存储在一个变量中,例如count,弹出堆栈计数时间元素。
情况2:如果堆栈为空,则只需以频率1将元素推入堆栈。
遍历完整的字符串时,如果堆栈的顶部元素的频率大于突发频率,则开始从堆栈(计数)次中删除元素。
现在,我们在堆栈中保留了剩余的元素,开始弹出它们并将其存储在字符串中,然后反转字符串以保留顺序。
返回新字符串。
更新:已解决。在这种情况下缺少一行if(ms.empty()== true || ms.top()。first!= s [i])弹出元素后,我们还必须插入字符频率为1的当前元素。
#include<iostream>
#include<stack>
using namespace std;
string solve(string s,int burstLen)
{
stack<pair<char,int>> ms;
for (int i = 0; i < s.size(); i++)
{
if (!ms.empty() && ms.top().first == s[i])
{
int count = ms.top().second;
ms.push({s[i],count + 1});
}
else
{
if(ms.empty() == true || ms.top().first != s[i])
{
if(!ms.empty() && ms.top().second >= burstLen)
{
int count = ms.top().second;
while(!ms.empty() && count--)
ms.pop();
ms.push({s[i],1});
}
else
ms.push({s[i],1});
}
}
}
if(!ms.empty() and ms.top().second >= burstLen)
{
int count = ms.top().second;
while(!ms.empty() && count--)
ms.pop();
}
string ans = "";
while (!ms.empty())
{
ans += ms.top().first;
ms.pop();
}
reverse(ans.begin(),ans.end());
return ans;
}
int main()
{
int t;
cin >> t;
while(t--)
{
string s;
int burstLen;
cin >> s >>burstLen;
cout << solve(s,burstLen) << "\n";
}
}