cincdx

cincdx

字符串的展开

链接:https://ac.nowcoder.com/acm/problem/16644
来源:牛客网

#include<bits/stdc++.h>
using namespace std;
string solve(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 i=b+1;i<e;i++)
	{
		for(int j=1;j<=p2;j++)
		{
			ans+=i;
		}
	}
	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 a;
	cin>>a;
	string ans="";
	for(int i=0;i<a.length();i++)
	{
		if(a[i]=='-')
		{
			ans+=solve(a[i-1],a[i+1],p1,p2,p3);
		}
		else 
		{
			ans+=a[i];
		}
	}
	cout<<ans<<endl;
	return 0;
}
  1. 发现遇到‘-’就会把字符串展开这个操作重复出现,就可以考虑封装一个函数
  2. 遍历字符串,我的方法是把它往后移,但这显然很麻烦,计算区间长度,复杂度变大。最优的方式是再创建一个字符串 ans 来存答案
    • 如果 a [i] 不是 '-'ans 就直接加
    • 如果是加上展开的字符串
  3. 如何展开?先排斥非法的情况
    • 第一种非法情况是 "a-b"->"ab","2-3"->"23" 这种,这个情况下,不管是字母还是数字,都可以统一理解为:后面字符比前面的字符 ASCII 码大 1,也就是 e-b == 1,这种情况下返回空字符串 ""(e 表示 '-' 前的字符,b 表示 '-' 后的字符。)
    • "减号两侧同为小写字母或同为数字,且按照 ASCII 码的顺序,减号右边的字符严格大于左边的字符。" 从反面入手,正面情况复杂,前字母后数字前数字后字母,到差不多吧
      然后就是去写这个 ans
    for(char i=b+1;i<e;i++)
    {
    	for(int j=1;j<=p2;j++)
    	{
    		ans+=i;
    	}
    }
    
	这个循环很巧妙,第一层是解决哪一个,第二层解决有几个
	
	然后p1=2**并且是字母**的时候,把填好的小写字母变成大写字母。大写字母就不用管了,这里还可以调用函数toupper (这里注意,这个并且是<mark class="hltr-orange">字母一定要判断</mark>,我就在这里wa了一发。)
	p1=3没啥
	最后反转直接调用函数reverse
上面的代码有错,1. 开头和结尾的‘-’,如“-a-d-”
```c++
if(a[i]=='-'&&i-1>=0&&i+1<a.length())
		{
			ans+=solve(a[i-1],a[i+1],p1,p2,p3);
		}

特殊情况的考虑

  1. 开头和结尾的‘-’,如 “-a-d-”
  2. 连续的‘-’,如 “---” 这行代码解决了这个问题
(isalpha(b)&&isalpha(e)&&b<e||isdigit(b)&&isdigit(e)&&b<e))
  1. 数字和字母之间的‘-’,如 “1-a”
  2. ‘-’左侧的字符大于右侧的,如 “d-a”
加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。