首页 > 其他分享 >PTAC语言删除字符串中的字串

PTAC语言删除字符串中的字串

时间:2023-11-17 20:01:30浏览次数:28  
标签:int s2 s1 PTA C语言 char len2 字串 字符串

PTAC语言删除字符串中的字串_PTA


这是题目。初见觉得还好,谁知道越分析越操蛋暗含深意。仔细看,假设我们通过遍历s1删除了两个显性的cat,哎,剩下的是什么

Tom is a male cat咋样,牛逼不。说明这题肯定会出现删除一次不够的样例sample

假设我们熟知C语言中#include<string.h>中的strcatstrstrstrcpy等函数,那么这题可以比较简洁。

首先大致介绍一下函数(C语言str函数系列-CSDN博客)这里有str函数的函数原型,如果想深入了解可以看看

strcat(s1,s2)是直接把s2接s1后面

strstr(s1,s2)可以返回一个char*的指针,指向s1字符串中第一次出现s2字符串的位置

strcpy(s1,s2)可以将s2拷贝到s1里。

#include<stdio.h>
#include<string.h>
int main()
{
	char s1[81] = { 0 };//注意,至少要81,因为题目说最大字符串为80,给'\0'预留一个位置,所以要81
	char s2[81] = { 0 };
	gets(s1);//用get函数读取字符串有两个好处,首先,输入不会被空格打断(scanf只读取空格之前的东西,空格之后的会被放在缓冲区)符合要求
	gets(s2);//其次,与fget相比,不会读到标志着字符串输入完毕的回车,在本例中,我们不需要回车.plus,vs编译器里只能用gets_s
	int len2 = strlen(s2);//取s2长度
	char* p = strstr(s1, s2);//用指针p存放s1中s2出现的位置,如果没有会接收到null空指针
	while ((p=strstr(s1,s2)) != NULL)//条件判断,因为有可能需要多次删除
	{
		char t[80];//用来储存s1中第一次出现s2之后的所有字符串
		strcpy(t,p+len2);//这里p+len2是因为char是一个字节的数据,所以在对地址操作时+len2就可以跳过len2个字符,即跳过s2
		//因为数组和指针本质都是地址,所以这里直接把p+len2传入,函数会从该位置开始读,直到读到'\0'为止,这里的'\0’是原来s1末尾的
    *p = '\0';//把p位置的字符改成'\0',对于s1来说等于直接舍去了p位置后面的字符
		strcat(s1, t);//直接接上,没啥好说的
	}
	puts(s1);//用puts函数,或者用printf("%s",s1),反正别用for加上printf("%1c",s1[i]),我当年就是这么写的,现在看看真的蠢
}

但是,假设我是个摆子,不知道string.h函数库里的函数,有没有办法硬刚呢。

有是有,但是不知道为啥我写的东西在pta平台的gcc编译器不认,实际上这段代码是没问题的

#include<stdio.h>
#include <string.h>
bool missle(char s1[], char s2[],int& i,int& len1,int& len2,int& flag)
{//这里的missle函数用于判断在s1的第i个字符是否后面接着s2的剩余部分
//由于程序运行到这有一个itr变量从i的位置向前飞,每飞一个字符就检查,像一个导弹一样哈哈哈
	int itr = 0;
	for (; itr < len2; itr++)
	{
		if (s1[i + itr] == s2[itr])//用itr往后遍历判断是否是要删除的字符
			continue;
		else
			return false;
	}
	flag = 1;//如果s1中真的还存在s2,把flag设为1,让whlie循环在跑一次
	i = i + itr - 1;直接把i放到s2后面的第一个字符,方便使用s1[n]=s1[i]
	return true;
}
int main()
{
	char s1[81] = { 0 };//还是一样,一定要81!!
	char s2[81] = { 0 };
	gets_s(s1);
	gets_s(s2);
	int flag = 1;//用于检查是否删完了
	while (flag)
	{
		int n = 0;
		flag = 0;//这里设为0保证等会的flag如果不受到改变,
        //就不会有下一个while循环
		int len2 = strlen(s2);
		int len1 = strlen(s1);
		int i = 0;
		for (; i < len1 - len2 + 1; i++)
		{
			if (missle(s1,s2,i,len1,len2,flag))
				continue;//如果是要删除的字符串s2,
                //利用循环本身的i++让i继续往后检查有没有可以用于替换s1[n]
                的字符
			else
			{
				s1[n] = s1[i];如果i位置不是要删除的字符,把i位置的字符向前移
				n++;//只有在i位置的字符前移了才有必要n++
			}
		}
		for (; i < len1; i++)
        //在i>=len1-len2之后,s1剩余长度小于s2,没有必要继续检查是否出现s2
		{
			s1[n] = s1[i];
			n++;
		}
		s1[n] = '\0';
	}
	printf("%s",s1);
}

这里用到了我搜的一种方法(C语言经典例32-删除字符串中指定的字符_c语言删除字符串中的指定字符,字符串和要删除-CSDN博客),他的方法是针对字符串中删除单个字符串的,很巧妙很值得学习和借鉴,我引用过来之后加了一个missle函数把判断单个字符是否一样变成了判断后面一大串字符是否一样

害,PTA害人不浅呐,这道题我折腾了快有十个小时,到现在才算是比较明白了,大家如果看的半懂不懂可以先了解str函数,然后试着自己写一次,至少先把第一种的简单的方法写出来,然后在慢慢理解第二种方法。

就算看懂了也要自己在写一遍,这种东西很经常眼睛:我懂了,脑子:好像吧,手:你说啥?


标签:int,s2,s1,PTA,C语言,char,len2,字串,字符串
From: https://blog.51cto.com/u_16356440/8453153

相关文章

  • C语言中的选择语句
    switch语句(一般使用在多分支的语句中,同时允许嵌套使用)最简单的格式如下:switch(整型表达式){ 语句项;}举个例子:#include<stdio.h>intmain(){intday=0;scanf("%d",&day)switch(day){case1: printf("星期一\n");case2: printf("星期二\n");case......
  • MATLAB/Simulink中调用C语言实现的传递函数
    1.引言在变流器控制中,通常采用C语言实现传递函数,且通常写成独立的C文件,本文简要介绍如何在MATLAB/Simulink中调用这些C文件。在本文中,采用C语言实现了一阶低通滤波器、二阶低通滤波器、滑动平均滤波器,具体代码见附录。同时需要安装C编译工具链,参考《UsingGCCwithMinGW》。2......
  • 使用C语言Beep()函数演奏歌曲
    曲子是大佬王宗贤的《孔雀之舞》,网上没有找到五线谱,只有简谱,而且曲子速度不明确。通过相关演奏音乐的可大体得知,因为连音较多,至10个小节处为24秒,所以每个小节是2.4秒,因为是2/4拍,每个小节是2拍,所以每半个拍子对应的时长是0.6秒,对应的是一个八分音符的音长,600毫秒在函数中用变量f控......
  • 入门c语言--3---关于qsort函数的一些理解
     qsort函数是c语言库函数的一种,作用是将所给的数组中的元素按要求进行排序。 qsort函数可以理解为冒泡函数的进阶,冒泡函数只能对一些如int,char等类型的数组进行排序,当遇到自主定义的struct类型的数组时便不能进行排序。此时便可以通过qsort函数进行排序。  在使用qsort函数......
  • PTA菜单计价4,5以及期中考试总结
    7-1菜单计价程序-4分数100全屏浏览题目切换布局作者 蔡轲单位 南昌航空大学本体大部分内容与菜单计价程序-3相同,增加的部分用加粗文字进行了标注。设计点菜计价程序,根据输入的信息,计算并输出总价格。输入内容按先后顺序包括两部分:菜单、订单,最......
  • 数据结构C语言之线性表
    发现更多计算机知识,欢迎访问Cr不是铬的个人网站1.1线性表的定义线性表是具有相同特性的数据元素的一个有限序列对应的逻辑结构图形:从线性表的定义中可以看出它的特性:(1)有穷性:一个线性表中的元素个数是有限的(2)一致性:一个线性表中所有元素的性质相同,即数据类型相同(3)序列性:各......
  • 实验4 C语言数组应用编程
    1实验任务1task1_1源代码1#include<stdio.h>2#defineN43voidtest1(){4inta[N]={1,9,8,4};5inti;6//输出数组a占用的内存字节数7printf("sizeof(a)=%d\n",sizeof(a));8//输出int类型数组a中每个元素的地址、值9for(i=0;i<N;......
  • c语言 函数参数个数影响
    参考:https://blog.csdn.net/Cheatscat/article/details/79306021https://blog.csdn.net/Dr_Haven/article/details/89383342一个函数的参数的数目过多(尤其是超过8个)显然是一种不可取的编程风格。参数的数目直接影响调用函数的速度,参数越多,调用函数越慢。参数的数目少,程序就显得......
  • c语言学习(文件)练习43
    需求:将10000以二进制的形式存入文件中#define_CRT_SECURE_NO_WARNINGS1#include<stdio.h>intmain(){ inta=10000; FILE*pf=fopen("D:\\桌面\\test.txt","wb"); fwrite(&a,1,1,pf); fclose(pf); pf=NULL; return0;} ......
  • C语言劳动节祝福程序代码
    帮您编写一段祝福程序代码,以下是一个400字以上的C语言劳动节祝福程序代码示例:#include<stdio.h>intmain(){//定义劳动节祝福语char*greetings[]={"在劳动节来临之际,向辛勤工作的您致以最诚挚的祝福!","感谢您为国家、为社会做出的无私贡献,祝......