【题目链接】
ybt 1848:【07NOIP提高组】字符串的展开
OpenJudge NOI 1.7 35:字符串的展开
洛谷 P1098 [NOIP2007 提高组] 字符串的展开
【题目考点】
1. 模拟
2. 字符串
【解题思路】
解法1:使用string类
复杂的模拟题建议使用string类来做。
设结果字符串s_ans
遍历字符串,遇到减号就做展开。
- 确定减号左右两侧的字符
- 设展开所产生的字符串s_ins,根据左右两侧的字符得知要添加的各个字符。
- 根据p1对要添加的字符做处理,将该字符添加p2个。
- 如果p3为2,那么再将s_ins反序。
- 最后将s_ins接在s_ans后面
如果没有遇到减号,那么直接将当前遍历到的字符接在s_ans后面
最后输出s_ans
解法2:使用字符数组
整体思路与解法1相同。
- 数组长度:考虑极端情况,长为100的字符串中有50个减号,都能展开每个展开都是a~z,每个字母最多8个(已知p2<=8)粗略估算结果最多有 24 ∗ 8 ∗ 50 + 50 = 9650 24*8*50+50=9650 24∗8∗50+50=9650,数组长度取10000即可。
- 字符数组末尾添加字符:使用数组填充写法。设字符数组s当前长度为len,要添加字符c:
s[len++] = c;
【题解代码】
解法1:使用string类, <cctype>函数
#include<bits/stdc++.h>
using namespace std;
int main()
{
int p1, p2, p3;
string s, s_ans;//s_ans:结果字符串
char lc, rc;
cin >> p1 >> p2 >> p3;
cin >> s;
s_ans.push_back(s[0]);
for(int i = 1; i < s.length(); ++i)//第0位置不看了,有减号也无法展开
{
if(s[i] == '-')
{
string s_ins;//要插入的字符串
lc = s[i-1];
rc = s[i+1];
if((islower(lc) && islower(rc) || isdigit(lc) && isdigit(rc)) && lc < rc)
{
for(char c = lc + 1; c <= rc - 1; ++c)//每次填充的字符c
for(int j = 1; j <= p2; ++j)//每个字符填充p2个
{
if(p1 == 3)
s_ins.push_back('*');
else if(isdigit(lc) || p1 == 1 && islower(lc))
s_ins.push_back(c);
else if(p1 == 2)
s_ins.push_back(toupper(c));
}
if(p3 == 2)
reverse(s_ins.begin(), s_ins.end());
}
else
s_ins.push_back('-');
s_ans += s_ins;//连接要插入的字符串
}
else
s_ans.push_back(s[i]);
}
cout << s_ans;
return 0;
}
解法2:使用字符数组,自己写函数做判断
#include<bits/stdc++.h>
using namespace std;
#define N 10000
int p1, p2, p3, l_a, l_i;//l_a:s_ans的长度 l_i:ins字符串的长度
char s[N], s_ans[N], s_ins[N];//ans:结果字符串 ins:要插入的字符串
bool isLower(char c)
{
return c >= 'a' && c <= 'z';
}
bool isDigit(char c)
{
return c >= '0' && c <= '9';
}
int main()
{
char lc, rc;
cin >> p1 >> p2 >> p3;
cin >> s;
s_ans[l_a++] = s[0];
int len = strlen(s);
for(int i = 1; i < len; ++i)//第0位置不看了,有减号也无法展开
{
if(s[i] == '-')
{
l_i = 0;//s_ins字符串的长度
lc = s[i-1];
rc = s[i+1];
if((isLower(lc) && isLower(rc) || isDigit(lc) && isDigit(rc)) && lc < rc)
{
for(char c = lc + 1; c <= rc - 1; ++c)//每次填充的字符c
for(int j = 1; j <= p2; ++j)//每个字符填充p2个
{
if(p1 == 3)
s_ins[l_i++] = '*';
else if(isDigit(lc) || p1 == 1 && isLower(lc))
s_ins[l_i++] = c;
else if(p1 == 2)
s_ins[l_i++] = c - 32;
}
if(p3 == 2)//倒序填充
{
for(int j = l_i - 1; j >= 0; --j)
s_ans[l_a++] = s_ins[j];
}
else//正序填充
{
for(int j = 0; j < l_i; ++j)
s_ans[l_a++] = s_ins[j];
}
}
else
s_ans[l_a++] = '-';
}
else
s_ans[l_a++] = s[i];
}
s_ans[l_a] = '\0';
cout << s_ans;
return 0;
}