emmmmm,这题慢慢悠悠做了40分钟。老年人了,好像一直在纠结怎么把代码写的比较优雅,结果还算是满意吧。写题录播大概可以在这里找到https://www.bilibili.com/video/BV1qt4y1B71u
题目有点长,要静下心来慢慢读,也没什么办法,就是模拟题。
下面是纠结了半天搞出来的,看起来可能比较优雅的思路?
1.把展开"-"的这个功能封装成函数,调用函数可以直接获得展开后的字符串
2.然后遍历字符串,
-
不是'-'的就把当前字符直接加到答案里(如果第一位或者最后一位是'-'的话,也是直接把这个字符放到答案字符串里),
-
是'-'的就把调用函数展开以后的结果加到答案字符串里。
3.然后去实现这个函数 首先排除掉非法情况,
第一种非法情况是"a-b"->"ab","2-3"->"23"这种,这个情况下,不管是字母还是数字,都可以统一理解为:后面字符比前面的字符ASCII码大1,也就是e-b==1,这种情况下返回空字符串""
(e表示'-'前的字符,b表示'-'后的字符。)
if(e-b==1){return "";}
第二种是不满足
"减号两侧同为小写字母或同为数字,且按照ASCII码的顺序,减号右边的字符严格大于左边的字符。"
就,大概用这种阴间代码实现了
if( ! ((isalpha(b) && isalpha(e) && b<e) ||
(isdigit(b) && isdigit(e) && b<e)))
{
然后我们先按正常填写的方式填写好,然后再处理p1=2并且是字母要大写的情况,和p1=3要变成'*'的情况,还有p3=2要反转的情况。
正常的填写方式就是这段代码
string ans = "";
for(char t = b+1 ; t < e ; t++)
{
for(int i = 0 ; i < p2 ; i++)
{
ans+=t;
}
}
然后p1=2并且是字母的时候,把填好的小写字母变成大写字母。(这里注意,这个并且是字母一定要判断,我就在这里wa了一发。)
if(p1 == 2 && isalpha(b))
{
for(int i =0 ; i <ans.length() ;i++)
{
ans[i] = ans[i]-'a'+'A';
}
}
p1=3的时候是变成*
if(p1 == 3)
{
for(int i =0 ; i< ans.length() ;i++)
{
ans[i] = '*';
}
}
p3=2的时候反转字符串(老年人了,用库函数吧 = = )
if(p3==2)
{
reverse(ans.begin(),ans.end());
}
下面是完整的代码
#include<iostream>
#include<algorithm>
using namespace std;
string fun(char b,char e,int p1,int p2,int p3)
{
if(e-b==1){return "";}
if( ! ((isalpha(b) && isalpha(e) && b<e) ||
(isdigit(b) && isdigit(e) && b<e)))
{
return "-";
}
string ans = "";
for(char t = b+1 ; t < e ; t++)
{
for(int i = 0 ; i < p2 ; i++)
{
ans+=t;
}
}
if(p1 == 2 && isalpha(b))
{
for(int i =0 ; i <ans.length() ;i++)
{
ans[i] = ans[i]-'a'+'A';
}
}
if(p1 == 3)
{
for(int i =0 ; i< ans.length() ;i++)
{
ans[i] = '*';
}
}
if(p3==2)
{
reverse(ans.begin(),ans.end());
}
return ans;
}
int main()
{
int p1,p2,p3;
cin >> p1 >> p2 >> p3;
string s;
cin >> s;
string ans = "";
for(int i = 0 ; i <s.length() ; i++ )
{
if(s[i]=='-'&& i-1>=0 && i+1<s.length())
{
ans += fun(s[i-1],s[i+1],p1,p2,p3);
}
else{
ans += s[i];
}
}
cout<<ans<<endl;
return 0;
}