洛谷P1098 字符串的展开

本文讲述了初学者如何使用C++ string类处理字符串中的减号,通过逻辑判断和函数应用,实现子串存储、减号处理与合并,重点讲解了同类字符的处理策略。

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

 初学string类,很多函数没有用到,且思维及其混乱;

首战:(5hAC)/(ㄒoㄒ)/~~

#include<iostream>
#include<cstdio>
#include<string>
using namespace std;
//1.找到减号 2.储存减号前的子串
//3.判断(5)来确定新串lon的起始位置
//4.填充减号串sub
//5.合并
//问题是新的lon头会是减号,所以要把减号也算进sub[i]内,解决这个问题后还要考虑结尾是减号时如何结束循环
int main()
{
	int p1, p2, p3, ri = 0, bi = 0, j, l,b=0,r=0, ch,flag=0;
	cin >> p1 >> p2 >> p3;
	getchar();
	string str[202], lon, sub[101], temp, ans;
	char k;
	cin >> lon;
	while (ch = lon.find('-'), ch != -1)
	{
		if (ch == lon.size() - 1)//若减号为最后一个,直接结束
			break;
		if(ch==0)//如果第一个是减号
		{str[ri]= lon.substr(0, 1);
		lon = lon.substr(ch + 1, lon.size() - str[ri].size());
		}
		else
		{
			str[ri] = lon.substr(0, ch); //2.储存减号前的子串

			if (((lon[ch + 1] <= '9' && lon[ch + 1] >= '0' && lon[ch - 1] <= '9' && lon[ch - 1] >= '0') && lon[ch + 1] > lon[ch - 1]) || ((lon[ch + 1] <= 'z' && lon[ch + 1] >= 'a' && lon[ch - 1] <= 'z' && lon[ch - 1] >= 'a') && lon[ch + 1] > lon[ch - 1]))
			{//同类且顺序


				if (lon[ch + 1] != lon[ch - 1] + 1)//如果不是相邻则拓展sub,是则不存减号于sub中
				{
					if (p1 == 1)
					{
						for (k = lon[ch - 1] + 1; k < lon[ch + 1]; k++)
							for (j = 1; j <= p2; j++)
								sub[bi] += k;
					}
					else if (p1 == 2&& lon[ch + 1] >= 'a' && lon[ch + 1] <= 'z')
					{
						for (k = lon[ch - 1] + 1 - 32; k < lon[ch + 1] - 32; k++)
							for (j = 1; j <= p2; j++)
								sub[bi] += k;
					}
					else if(p1 == 2 && lon[ch + 1] >= '0' && lon[ch + 1] <= '9')
					{
						for (k = lon[ch - 1] + 1; k < lon[ch + 1]; k++)
							for (j = 1; j <= p2; j++)
								sub[bi] += k;
					}
					else
					{
						for (k = lon[ch - 1] + 1; k < lon[ch + 1]; k++)
							for (j = 1; j <= p2; j++)
								sub[bi] += '*';
					}
					if (p3 == 2)
					{
						temp = "";
						for (l = 0; l < sub[bi].size(); l++)
							temp += sub[bi][sub[bi].size() - l - 1];//string类数组str一个一个字符进行初始化时,不能用str[0],str[1]...如此初始化,而要用+=要输入的字符
						for (l = 0; l < sub[bi].size(); l++)
							sub[bi][l] = temp[l];
					}
					bi++;
				}



				lon = lon.substr(ch + 1, lon.size() - str[ri].size() - 1);

			}
			else //两边不同类或逆序,sub为减号
			{
				sub[bi] = '-';
				lon = lon.substr(ch + 1, lon.size() - str[ri].size() - 1);
				bi++;
			}
		}
		ri++;
	}
	if (ri == 0)
		cout << lon;
	else
	{
		int maxn;

		if (ri > bi)
			maxn = ri;
		else
			maxn = bi;
			
		
		for (j = 0;j<=maxn; j++)
		{
			while (str[r][0] == '-')
			{
				ans += '-';
				r++;
			}
			if(r<ri)
			ans += str[r];
		if (r >= ri - 1)
			flag = 1;
		if (flag == 1)
		{
			if (b < bi)
				ans += sub[b++];
		}
			else if(str[r][str[r].size()-1]!=str[r+1][0]-1&&b<bi)
			ans += sub[b++];
			r++;
		}
		ans += lon;
		cout << ans;

	}

}

总结:

1.c++可以使用万能头include<bits/stdc++.h>,其包括<string>在内的所有头文件;

2.见难题一定要先用纸写下尽可能详细的思路;

3.拓展几个新的函数,详见(24条消息) C++string类_XiaoYao1217的博客-优快云博客

1、s.erase(x,y) 表示将字符串s从x位置起删除y个字符

2、s.insert(x,y) 表示将字符串y(或字符y)插入到s的x位置处

3、s.push_back(x) 表示在s的末尾插入字符x

4、reverse(s.begin(),s.end()) 将字符串s翻转

4.VS2019调试可以设置断点后,右键断点设置断点条件,条件可以为表达式或flag的值;

二战:

#include<iostream>
#include<string>		
#include<algorithm>
using namespace std;
//展开的情况:同类&&右边大于左边&&不相邻
//相邻:删除减号
//其他:保留减号
int main()
{
	int p1, p2, p3, i=0,j,k,l;
	string str,tmp,re;
	cin >> p1 >> p2 >> p3;
	cin >> str;
	while(str[i]!='\0')
	{

		if (i>=1&&str[i] == '-' && ((str[i - 1] >= '0' && str[i - 1] <= '9'&&str[i + 1] >= '0' && str[i + 1] <= '9') || (str[i - 1] >= 'a' && str[i - 1] <= 'z'&&str[i + 1] >= 'a' && str[i + 1] <= 'z')) && str[i + 1] > str[i - 1] && str[i - 1] + 1 != str[i + 1])
		{
			tmp = "";
			if (p1 == 1 || (p1 == 2 && (str[i - 1] >= '0' && str[i - 1] <= '9')))
			{
				l = 0;
				for (j = 0; j < str[i + 1] - str[i - 1] - 1; j++)
					for (k = 0; k < p2; k++)
						tmp+= char(str[i - 1] + j + 1);
			}
			else if (p1 == 2)
			{
				for (j = 0; j < str[i + 1] - str[i - 1] - 1; j++)
					for (k = 0; k < p2; k++)
						tmp += char(str[i - 1] + j + 1 - 32);
			}
			else if (p1 == 3)
			{
				for (j = 0; j < str[i + 1] - str[i - 1] - 1; j++)
					for (k = 0; k < p2; k++)
						tmp += '*';
			}
			if (p3 == 2)
				reverse(tmp.begin(),tmp.end());
			str.erase(i, 1);
			str.insert(i,tmp);
			i += tmp.size();//2-5->2345,i=1->i=3
		}
	else if(str[i] == '-'&&i>=1&&str[i - 1] + 1 == str[i + 1])
	{
		str.erase(i,1);
	}
	
	i++;
	}
	cout << str;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值