天梯赛备赛之字符串模拟

鉴于自己比较弱,而且好多东西都已经遗忘又偷懒不练,那只能做几道题捡起来多少算多少,以一种合集的方式展现给大家,也给自己最近做的题目算是一个交代吧

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 分) 字符串模拟

本题要求你计算AB。不过麻烦的是,AB都是字符串 —— 即从字符串A中把字符串B所包含的字符全删掉,剩下的字符组成的就是字符串AB

输入格式:

输入在2行中先后给出字符串AB。两字符串的长度都不超过104,并且保证每个字符串都是由可见的ASCII码和空白字符组成,最后以换行符结束。

输出格式:

在一行中打印出AB的结果字符串。

输入样例:

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;
}

未完待续....请提醒作者更新。。。

posted @ 2022-03-14 22:54  yuezi2048  阅读(42)  评论(0编辑  收藏  举报