你想要的字符串展开算法在这
字符串的展开
目:链接:登录—专业IT笔试面试备考平台_牛客网 来源:牛客网
在初赛普及组的“阅读程序写结果”的问题中,我们曾给出一个字符串展开的例子:如果在输入的字符串中,含有类似于“d-h”或“4-8”的子串,我们就把它当作一种简写,输出时,用连续递增的字母或数字串替代其中的减号,即,将上面两个子串分别输出为“defgh”和“45678”。在本题中,我们通过增加一些参数的设置,使字符串的展开更为灵活。具体约定如下: (1)遇到下面的情况需要做字符串的展开:在输入的字符串中,出现了减号“-”,减号两侧同为小写字母或同为数字,且按照ASCII码的顺序,减号右边的字符严格大于左边的字符。 (2)参数 p1p_1p1:展开方式。p1=1p_1=1p1=1 时,对于字母子串,填充小写字母;p1=2p_1=2p1=2 时,对于字母子串,填充大写字母。这两种情况下数字子串的填充方式相同。p1=3p_1=3p1=3时,不论是字母子串还是数字子串,都用与要填充的字母个数相同的星号“*”来填充。 (3)参数 p2p_2p2:填充字符的重复个数。p2=kp_2=kp2=k 表示同一个字符要连续填充 kkk 个。例如,当 p2=3p_2=3p2=3 时,子串“d-h”应扩展为“deeefffgggh”。减号两侧的字符不变。 (4)参数 p3p_3p3:是否改为逆序:p3=1p_3=1p3=1 表示维持原有顺序,p3=2p_3=2p3=2 表示采用逆序输出,注意这时仍然不包括减号两端的字符。例如当 p1=1、p2=2、p3=2p_1=1、p_2=2、p_3=2p1=1、p2=2、p3=2 时,子串“d-h”应扩展为“dggffeeh”。 (5)如果减号右边的字符恰好是左边字符的后继,只删除中间的减号,例如:“d-e”应输出为“de”,“3-4”应输出为“34”。如果减号右边的字符按照ASCII码的顺序小于或等于左边字符,输出时,要保留中间的减号,例如:“d-d”应输出为“d-d”,“3-1”应输出为“3-1”。
所有的测试案例,均为自己随机生成的。并且验证结果百分百正确
输入描述
第一行输入的数据是三个p值,第二行输入的是一个长度不超过100的字符串。
实例:
第一行输入:1 2 1
第二行输入:1-a-v-5-9
输出:1-abbccddeeffgghhiijjkkllmmnnooppqqrrssttuuv-56677889
第一行输入:1 2 2
第二行输入:abs-cc-98-aa
输出:abs-cc-98-aa
第一行输入:1 2 1
第二行输入:-abcs-w1234-9s-4zz
输出:-abcsttuuvvw1234556677889s-4zz
题目分析:
阅读完题目,我们可以知道题目的本质就是在写for循环,写if_else语句。 核心的思想: 根据字符串中的每一个字符,以及‘-’左右的字符之间的联系,来一个个打印输出的字符,遍历到最后一个字符的时候,可以得到一个正确的字符串
- 算法设计顺序遍历字符串,当遇到字符串中的某个字符是‘-’时,才需要做出判断。否则只需要打印原来的字符。比如:123-9这个简单纯数字的字符串,在下标为0,1,2,4的时候,我们只需要输出原来的字符;在下标为3的时候,我们才需要对输出进行判断,上面的例子,我们肯定是要拓展字符串数组的。只有当字符串中出现的某个小区间为a-5,4-a,a–f,时我们才直接输出‘-’,这里将上面说所的例子当字符不是‘-’的时候联系一起,所设计的算法如下。
if(s[i]!='-'||(int(s[i-1])<=57&&(int)s[i+1]>=97&&s[i]=='-')||
(int(s[i-1])>=97&&(int)s[i+1]<=57&&s[i]=='-')||(s[i+1]=='-'&&s[i]=='-')||
(s[i-1]=='-'&&s[i]=='-')){
cout<<s[i];
}
- 当‘-’左右的字符是一样的时候,输出‘-’字符。
if(s[i-1]==s[i+1]){
cout<<'-';
}
- 碰到要拓展的情况是‘-’左边的字符对应的ASCII码小于右边的ASCII码值,我们才需要拓展。拓展的冗长的代码。
- 符号解释:p1用来判断输出的字符的格式,即输入的是小写字母,大写字母,还是*号 p2用来判断输出的一个字符输出的次数。 p3用来判断输出的数据是正序输出的还是逆向输出的 n = (int)s[i+1]-(int)s[i-1];用来记录字符串中的字符的个数
- 拓展的算法
if(p1==1){
if(p3==1){
for(int m = 0;m<n-1;m++){
for(int j = 0;j<p2;j++){
cout<<char(s[i-1]+m+1);
}
}
}else{
for(int m = n-2;m>=0;m--){
for(int j = 0;j<p2;j++){
cout<<char(s[i-1]+m+1);
}
}
}
}else if(p1==2){
if(p3==1){
for(int m = 0;m<n-1;m++){
for(int j = 0;j<p2;j++){
if((int)s[i-1]>=65){
cout<<char(s[i-1]+m-31);
}
else{
cout<<char(s[i-1]+m+1);
}
}
}
}else{
for(int m = n-2;m>=0;m--){
for(int j = 0;j<p2;j++){
if((int)s[i-1]>=65){
cout<<char(s[i-1]+m-31);
}else{
cout<<char(s[i-1]+m+1);
}
}
}
}
}else{
for(int m = 0;m<p2;m++){
for(int i = 0;i<n-1;i++){
cout<<'*';
}
}
}
}else{
cout<<'-';
}
题目完整代码:
#include<bits/stdc++.h>
#include<iostream>
using namespace std;
int main(){
int p1,p2,p3;
string s;
cin>>p1>>p2>>p3;
cin>>s;
cout<<s[0];
for(int i = 1;i<s.size();i++){
if(s[i]!='-'||(int(s[i-1])<=57&&(int)s[i+1]>=97&&s[i]=='-')||
(int(s[i-1])>=97&&(int)s[i+1]<=57&&s[i]=='-')||(s[i+1]=='-'&&s[i]=='-')||
(s[i-1]=='-'&&s[i]=='-')){
cout<<s[i];
}
else{
if(s[i-1]==s[i+1]){
cout<<'-';
}else if(s[i-1]<s[i+1]){
int n = (int)s[i+1]-(int)s[i-1];
if(p1==1){
if(p3==1){
for(int m = 0;m<n-1;m++){
for(int j = 0;j<p2;j++){
cout<<char(s[i-1]+m+1);
}
}
}else{
for(int m = n-2;m>=0;m--){
for(int j = 0;j<p2;j++){
cout<<char(s[i-1]+m+1);
}
}
}
}else if(p1==2){
if(p3==1){
for(int m = 0;m<n-1;m++){
for(int j = 0;j<p2;j++){
if((int)s[i-1]>=65){
cout<<char(s[i-1]+m-31);
}
else{
cout<<char(s[i-1]+m+1);
}
}
}
}else{
for(int m = n-2;m>=0;m--){
for(int j = 0;j<p2;j++){
if((int)s[i-1]>=65){
cout<<char(s[i-1]+m-31);
}else{
cout<<char(s[i-1]+m+1);
}
}
}
}
}else{
for(int m = 0;m<p2;m++){
for(int i = 0;i<n-1;i++){
cout<<'*';
}
}
}
}else{
cout<<'-';
}
}
}
}
相关文章
- 语音信号滤波去噪——使用FLATTOPWIN设计的FIR滤波器
- 剑指36-两个链表中第一个共同的节点
- 通信工程交换传输实习报告
- 剑指37-数字在排序数组中出现的次数
- STM32系统时钟树分析
- canvas 文字特效-6个典型的HTML5文字特效示范
- 两个HC05蓝牙模块相互之间的通信
- 剑指38-二叉树的深度
- c语言编译器在线-c在线编译器(c语言在线编程)
- Arduino Mega 2560 Reference Design原理图解读
- fscanf读取一行字符串-语言文件操作
- 剑指40-数组中只出现一次的数字
- c语言编译器
- 剑指41-和为S的连续正整数序列
- 数据手套的设计与实现
- fscanf读取一行字符串-C语言文件流(字节流) IO 操作(二) —— 初识“流”以及文件的顺序读写(f
- 基于MATLAB的AM调制解调
- 剑指42-和为S的两个数
- fscanf读取一行字符串-C中带有fscanf的无延迟循环
- STM32GPIO部分介绍