P1098 [NOIP2007 提高组] 字符串的展开

文章介绍了如何使用C++编写一个函数来处理字符串中的减号,检查其两侧字符是否符合特定条件,如字母或数字,并进行字符替换、删除或插入操作。作者提供了一个简化后的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、思路

1、看一下减号两边的是不是同为小写字母或者同为数字

bool is_cm(char a,char b)
{
	return (a>=97&&b<=122&&b>=97&&b<=122)||(a>=48&&a<=57&&b>=48&&b<=57);
}

2、如果是的话,下一步,看看减号两边相差多少,如果相差1,说明是后继,直接删掉减号

int sub(char a,char b)
{
	int t = b-a;
	return t;
}

3、如果不相差1,看看相差多少,大于1,说明有得填充,小于1,说明不做处理,因为不符合左边严格小于右边

4、根据p2得值填充多少个

5、根据p3得值决定是否逆序

6、我觉得把要添加得新造一个字符串,后面再添加到原字符串中会更好

2、我的完整代码如下:

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;

const int N = 110;

string s;

int p1,p2,p3;
bool is_cm(char a,char b)
{
	return (a>=97&&b<=122&&b>=97&&b<=122)||(a>=48&&a<=57&&b>=48&&b<=57);
}
bool is_m(char a,char b)
{
	return (a>=48&&a<=57&&b>=48&&b<=57);
}
int sub(char a,char b)
{
	int t = b-a;
	return t;
}
int main()
{
	cin>>p1>>p2>>p3;
	cin>>s;
	
	// 寻找减号
	for(int i = 0,j=0;i<s.size();i++)
	{
		string str = "";
		if(s[i]=='-')
		{
			j = i-1;
			if(is_cm(s[j],s[i+1]))//判断字母或者是数字 
			{
				int t = sub(s[j],s[i+1]);
				if(t==1)// 直接删去减号 
				{
					s.erase(i,1);// 删除该减号 
				}
				else if(t>1)
				{
					//先删除该减号
					s.erase(i,1);
					if(p1==1&&!is_m(s[j],s[i+1])||(p1==1&&is_m(s[j],s[i+1]))||(p1==2&&is_m(s[j],s[i+1])))// 插入小写字母或者直接数字 
					{
						for(int m = 1,k = 0;m<t;k+=p2,m++)
						{
							str.append(p2,s[j]+m);
						} 
						if(p3==1)
						{
							s = s.substr(0,i) + str + s.substr(i);
						}
						else if(p3==2)// 加上那个被塑造的字符串,且是倒序 
						{
							reverse(str.begin(),str.end());
							s = s.substr(0,i)+str + s.substr(i);
						}
					}
					else if(p1==2&&!is_m(s[j],s[i+1]))// 插入大写字母
					{
						for(int m = 1,k = 0;m<t;m++)
						{
							str.append(p2,s[j]+m-32);
						}
						if(p3==1)
						{
							s = s.substr(0,i) + str + s.substr(i);
						}
						else if(p3==2)// 加上那个被塑造的字符串,且是倒序 
						{
							reverse(str.begin(),str.end());
							s = s.substr(0,i)+str + s.substr(i);
						}	
					}
					else if(p1==3)
					{
						s.insert(i,(t-1)*p2,'*');	
					} 
				} 
			}
		}
	 }
	 cout<<s<<endl; 
	 return 0; 
}

 3、erase得用法

代码中提到的s.erase(i,1)其实本质得用法是如下

s.erase(pos,n) 从0开始得第pos位置开始后面n个字符删掉

还有其他得用法

erase(迭代器),删除迭代器指向得那个字符

erase(迭代器,迭代器),删除两个迭代器之间的,但不包括后面的那个

4、append的用法

详细请看这个大佬的博客C++的append的用法

 5、insert的用法

insert用于在某个位置插入多少个*号

s.insert(位置,数量,字符),比如上面的就是在第i个位置插入特定数量的*

若要看其他的用法,在这里 insert的用法

6、更加简洁的代码解决本题

#include <iostream>
#include <string>
#include <cctype>
#include <algorithm>

using namespace std;

string expand(const string& str, int p1, int p2, int p3) {
    string result;
    for (size_t i = 0; i < str.length(); ++i) {
        if (str[i] == '-' && i > 0 && i + 1 < str.length() && 
            ((isalpha(str[i - 1]) && isalpha(str[i + 1]) && str[i - 1] < str[i + 1]) ||
             (isdigit(str[i - 1]) && isdigit(str[i + 1]) && str[i - 1] < str[i + 1]))) {
            for (char c = str[i - 1] + 1; c < str[i + 1]; c++) {
                for (int j = 0; j < p2; ++j) {
                    char ch = c;
                    if (p1 == 2 && isalpha(ch)) ch = toupper(ch);
                    if (p1 == 3) ch = '*';
                    result += ch;
                }
            }
            if (p3 == 2) {
                reverse(result.end() - (str[i + 1] - str[i - 1] - 1) * p2, result.end());
            }
        } else {
            result += str[i];
        }
    }
    return result;
}

int main() {
    int p1, p2, p3;
    string str;
    cin >> p1 >> p2 >> p3;
    cin >> str;

    cout << expand(str, p1, p2, p3) << endl;
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值