天梯赛备赛之字符串模拟
鉴于自己比较弱,而且好多东西都已经遗忘又偷懒不练,那只能做几道题捡起来多少算多少,以一种合集的方式展现给大家,也给自己最近做的题目算是一个交代吧
1.同学提问的问题汇总
1.如何忽略空格读入一行字符
在java语言中很简单,直接String str = input.nextLine();不过后续需要注意一些回车\t\r这个读入的问题,鄙人java忘得差不多了,就记先一下
然而在C语言中,我们可以用scanf的正则用法,因为scanf默认是读入空格和回车符结束输入的。
但是运用此表达式可以忽略空格。
scanf("%[^\n]",str);
另外也从别人的代码发现了另一种写法,特此记录。
这种方法更易理解,读者看着用就可。
while( (str[j] = getchar()) != '\n') j ++ ;
2.关于scanf的问题,该不该加&号的问题
多说无益,直接对照关于scanf的说明:
scanf("<格式说明字符串>",<变量地址>);
OK,后面输入的是地址,从目前来说,如果是单个数据,比如int,char类型的数据,要获得他的地址,是需要在前面加‘&’标志来获取地址的,但是字符串在C语言里是一个存储字符类型的数组,我们知道数组的地址是连续的,而数组名是表示字符串的首地址,那么在输入的时候就不需要加’&'标志。
2.一些例题
L1-011 A-B (20 分) 字符串模拟
本题要求你计算A−B。不过麻烦的是,A和B都是字符串 —— 即从字符串A中把字符串B所包含的字符全删掉,剩下的字符组成的就是字符串A−B。
输入格式:
输入在2行中先后给出字符串A和B。两字符串的长度都不超过104,并且保证每个字符串都是由可见的ASCII码和空白字符组成,最后以换行符结束。
输出格式:
在一行中打印出A−B的结果字符串。
输入样例:
I love GPLT! It's a fun game!
aeiou
输出样例:
I lv GPLT! It's fn gm!
因为长度不是很大,所以思路比较暴力,两个for循环,无非就是输入原始字符串,和待比较字符串。
遍历原始字符串,然后在待比较字符串中遍历查找有没有一样的
如果有,退出,不输出
如果没有,就说明在待比较字符串中没有对应的字符与原始的相同,输出相应字符即可。
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
char str1[10005],str2[10005];
scanf("%[^\n]",str1);
getchar();
scanf("%[^\n]",str2);
for(int i=0;i<strlen(str1);i++){
int j;
for(j=0;j<strlen(str2);j++){
if(str1[i]==str2[j]){
break;
}
}
if(j==strlen(str2)) cout<<str1[i];
}
return 0;
}
L1-039 古风排版 (20 分) 字符串模拟)
https://pintia.cn/problem-sets/994805046380707840/problems/994805091888906240
中国的古人写文字,是从右向左竖向排版的。本题就请你编写程序,把一段文字按古风排版。
输入格式:
输入在第一行给出一个正整数N(<100),是每一列的字符数。第二行给出一个长度不超过1000的非空字符串,以回车结束。
输出格式:
按古风格式排版给定的字符串,每列N个字符(除了最后一列可能不足N个)。
输入样例:
4
This is a test case
输出样例:
asa T
st ih
e tsi
ce s
此处难点在于row应该是多少,解决办法之一是多写几组数据验证找规律,题写得少的无奈之举。
#include<stdio.h>
#include<string.h>
int main(){
int n;
scanf("%d",&n);
getchar();
char str[1000];
scanf("%[^\n]",str);
int count =0;
int row = (strlen(str)-1) /n +1 ;
char out[n][row];
for(int i=0;i<n;i++){
for(int j=0;j<row;j++){
out[i][j]=' ';
}
}
for(int i=row-1;i>=0;i--){
for(int j=0;j<n;j++){
out[j][i]=str[count];
count++;
if(count==strlen(str)) {break;}
}
}
for(int i=0;i<n;i++){
for(int j=0;j<row;j++){
printf("%c",out[i][j]);
}
printf("\n");
}
return 0;
}
L1-058 6翻了 (15 分) 字符串模拟
“666”是一种网络用语,大概是表示某人很厉害、我们很佩服的意思。最近又衍生出另一个数字“9”,意思是“6翻了”,实在太厉害的意思。如果你以为这就是厉害的最高境界,那就错啦 —— 目前的最高境界是数字“27”,因为这是 3 个 “9”!
本题就请你编写程序,将那些过时的、只会用一连串“6666……6”表达仰慕的句子,翻译成最新的高级表达。
输入格式:
输入在一行中给出一句话,即一个非空字符串,由不超过 1000 个英文字母、数字和空格组成,以回车结束。
输出格式:
从左到右扫描输入的句子:如果句子中有超过 3 个连续的 6,则将这串连续的 6 替换成 9;但如果有超过 9 个连续的 6,则将这串连续的 6 替换成 27。其他内容不受影响,原样输出。
输入样例:
it is so 666 really 6666 what else can I say 6666666666
输出样例:
it is so 666 really 9 what else can I say 27
思路复盘一下:
1.读入字符串
2.遍历每个元素,在遍历过程中需要统计6的个数:
如果没有就输出原来的字符
如果有就contunue,继续找下一个
最后输出的时候根据题目要求,超过9个输出27,超过3个输出9,其他情况就输出cnt个6
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
char str[1005];
scanf("%[^\n]",str);
int cnt=1;
for(int i=0;i<strlen(str);i++){
if(*(str+i)=='6' && *(str+i+1)=='6'){
cnt++;
continue;
}
if(cnt>9) cout<<"27";
else if(cnt>3) cout<<"9";
else if(cnt>1)
for(int i=0;i<cnt;i++) cout<<"6";
else cout<<*(str+i);
cnt=1;
}
return 0;
}
未完待续....请提醒作者更新。。。