原题链接:P1098字符串的展开
本体为模拟题,不过情况比较复杂,考验细节
注意点:
- 连续’-',可能会出现一些奇怪的东西,例: 7 − − − − 9 a − b 7----9a-b 7−−−−9a−b(应为 2 − − − 9 a b 2---9ab 2−−−9ab)
- 末尾/开头的’-',如: − − 2 − 9 − − --2-9-- −−2−9−−(应为 − − 23456789 − − --23456789-- −−23456789−−)
- 确定’-'两边同时为字母或者数字并且左边数字比较小
- 连续字符 如: a − b − c − d − e − f − g a-b-c-d-e-f-g a−b−c−d−e−f−g(应为: a b c d e f g abcdefg abcdefg)
使用到的库函数介绍:
-
库
isalpha(x) 判断x是否为字母 isdigit(x) 判断x是否为数字 islower(x) 判断x是否为小写字母 isupper(x) 判断x是否为大写字母 isalnum(x) 判断x是否为字母或数字 ispunct(x) 判断x是否为标点符号 isspace(x) 判断x是否为空格 //如果x符合条件,均会返回true,否则返回false toupper(x) 如果x是小写字母,将其转换成大写字母 tolower(x) 如果x是大写字母,将其转换成小写字母
-
库
s.erase(x,y) 表示将字符串s从x位置起删除y个字符 s.insert(x,y) 表示将字符串y(或字符y)插入到s的x位置处 s.push_back(x) 表示在s的末尾插入字符x reverse(s.begin(),s.end()) 将字符串s翻转
笔者有点懒(bushi),省了一些手写的时间
AC代码:
#include<bits/stdc++.h>
using namespace std;
int p1,p2,p3;
string s;
int main(){
cin>>p1>>p2>>p3;
cin>>s;
for(int i=1;i<s.length()-1;i++){
//从字符串的第二位开始循环查找到倒数第二位
//因为'-'号如果出现在首位或者末尾都肯定是不用管的
if(s[i]=='-'&&((islower(s[i-1])&&islower(s[i+1])&&s[i-1]<s[i+1])||(isdigit(s[i-1])&&isdigit(s[i+1])&&s[i-1]<s[i+1])))
{
//判断题目中的“约定1”成立
//这里根据p1值的不同只需要对程序做简要的修改
if(p1==1){
s.erase(i,1);//删去'-'号所在的那一位
string spare="";//建立一个空的备用字符串
for( int k=s[i-1]+1;k<=s[i]-1;k++)
//注意:这里已经删除'-'号,所以是k<=s[i]-1
{//循环
char ch=k;
for(int j=1;j<=p2;j++) spare.push_back(ch);
//在spare的末尾不断插入p2个字母
}
if(p3==2) reverse(spare.begin(),spare.end());
//如果p3=2就把spare翻转
s.insert(i,spare);
//在s中删去'-'的位置插入spare
}
else if(p1==2){
s.erase(i,1);
string spare="";
for(int k=s[i-1]+1;k<=s[i]-1;k++){
char ch=k;
ch=toupper(ch);//将原小写字母转成大写
for(register int j=1;j<=p2;j++) spare.push_back(ch);
}
if(p3==2) reverse(spare.begin(),spare.end());
s.insert(i,spare);
}
else if(p1==3){
s.erase(i,1);
string spare="";
for(int k=s[i-1]+1;k<=s[i]-1;k++)
for(int j=1;j<=p2;j++) spare.push_back('*');//与字母个数相同的星号
if(p3==2) reverse(spare.begin(),spare.end());
s.insert(i,spare);
}
}
}
cout<<s;
return 0;
}