算法题(117):字符串的展开

算法题(117):字符串的展开_第1张图片

审题:

本题需要我们根据题目的要求将字符串进行扩展

思路:
方法一:模拟法

一般来说题目字数和要求很多的题就是模拟题,模拟题特别需要注意的就是细节,在编写代码之前一定要把细节想清楚,否则很容易出错。

分析模拟过程:

首先,题目给了我们一个字符串,这个字符串中的某些部分是需要扩展的,有些部分是不用扩展的,在这里我们就分成这两大类

需要扩展:

(1)特殊扩展:对于'-'两边的字符属于顺序递增的情况,我们就直接越过'-'接入output

(2)普通扩展:

控制插入字符:通过if语句控制字母与数字字符的插入字符

控制插入数量:通过append方法控制p2个字符插入

控制插入顺序:通过reverse方法控制p3为2时的顺序

不需要扩展:直接接入output字符串

解题:

#include
#include
using namespace std;
int p1, p2, p3;
string input;
string output;
bool issametype(char a, char b)
{
	return (islower(a) && islower(b)) || (isdigit(a) && isdigit(b));
}
int main()
{
	cin >> p1 >> p2 >> p3;
	cin >> input;
	//输出字符串构建
	for (size_t i = 0; i < input.size(); i++)
	{
		//扩展
		if (i > 0 && i < input.size() - 1 && input[i] == '-' && issametype(input[i-1],input[i+1]) && input[i+1] > input[i-1])
		{
             //特殊扩展
			if (input[i - 1] + 1 == input[i + 1])
			{
				continue;
			}
			string s;
			//确定待插入临时串s
			for (char c = input[i - 1] + 1; c < input[i + 1]; c++)
			{
				char ch;
				//展开方式+重复个数
					if (p1 == 2)
					{
						if (islower(c))//小写字母单独处理
							ch = toupper(c);
						else//数字处理
							ch = c;
					}
					else if (p1 == 3)
					{
						ch = '*';
					}
					else
					{
						ch = c;
					}
					s.append(p2, ch);		
			}
			//插入顺序
			if (p3 == 2)
			{
				reverse(s.begin(),s.end());
			}
			//插入
			output += s;
		}
		else //不展开
		{
			output += input[i];
		}	
	}
	cout << output;
}

注意:

1.利用库方法isdigit判断是否为数字字符,islower判断是否为小写字母。

2.判断越界不要使用i-1,因为i是size_t类型,-1后会变成很大的正数,导致逻辑错乱。

3.对于输出类型部分:p1为1和3对于数字的字母都是一样的,而p1为2就需要分开处理

4.toupper将小写字母转大写,append将多个重复字符插入字符串

P1098 [NOIP 2007 提高组] 字符串的展开 - 洛谷

你可能感兴趣的:(算法题,算法)