删除原字符串的子串(c++内置find函数好啊)

一、前言

写这篇博客的来源是一位名叫狗子的同学问了一个类似的问题,这应该是某个学校的c语言程序设计的填空题目吧?反正,那个时候看到题目花里胡哨的写法,用了四个指针,但是其实也是用到了双指针的想法,所以还是过来写下这一篇博客,一个解决那一个题目的思路,另外用STL内置函数find去实现这样的题目,当然目前只是测试了几个样例都对了,如果有什么错误的地方,欢迎广大读者及时纠正,我也会及时的改正的!!

二、题目描述

删除原字符串的子串(c++内置find函数好啊)

三、题目分析

大家可以看一看本题应当怎么思考,其实还是有一定的思考难度的,那么我们关注到的问题就是,为什么要利用四个指针?且最后输出应当怎么办呢?带着这样的疑问进行接下来的一个分析。至于具体的分析过程已经作为注释标在最终的代码里面了,大家可以一步一步跟着走。

四、完整代码

/*void fun(char s[],char c[])  //s表示原字符串,c表示要删除的子串 
{
	int i=0;
	//q代表原字符串,q代表最终字符串,r代表待删除的子串,t用来过渡中间的删除过程 
	char *p,*q,*r,*t;
	p=s;q=s;r=c;
	while(*p)         //p相当于从头到尾的遍历原字符串 
	{
		while(*r!='\0'&&*p!='\0'&&*p==*r)   //r进行每一次的子串删除 
		{
			p++;r++;  
		}
	//*******************************//	if(*p=='\0') break;  //原字符串遍历完毕直接跳出
		
		if(*r=='\0')   //代表在子串遍历过程中,原串产生了完全长度的子串 
		{
			t=q;   //t记录下来删除的那一瞬间q所指向的位置,便于之后的q移动后复原
			
			while(*p) {*q=*p;p++;q++;}  //此处是把删除某个子串之后的所有字符赋给q 
			
			*q='\0';q=t;p=q;r=c;  //*q为'\0'代表在删完之后的串的最后加一个'\0'.
		 }
		 else   //如果没有找到重复的,指针往后移动,子串重新指向首地址
		 {
		 	q++;p=q;r=c;
		  } 
	}
	q=s;      //让最终输出的指针指向首地址
	while(*q)
	{
		cout<<*q<<" ";
		q++;
	}
}
int main()   //测试的程序
{
	char s[10];
    char c[3];
    cin>>s;
    cin>>c;
    fun(s,c);
}

五、原题问题分析

在测试样例的时候,本蒟蒻发现,如果按照原本的思想进行的话,是没有办法删除后缀子串的。例如。

删除原字符串的子串(c++内置find函数好啊)

当我们删掉那一段之后 (if(*p=='\0') break;)结果便是这样的:

删除原字符串的子串(c++内置find函数好啊)

结果就对了,这是为什么呢?因为最外层的循环就是p!='\0'才会进行,但是如果删除最后的那一段子串,我们会发现,在进行while外层函数里面的第一个while之后,*p已经满足后面的break条件了,因此,直接跳出,不再进行后面的删除工作了,大家可以好好的看一看,走一走程序! 

六、STL内置函数(find)的解法

#include<bits/stdc++.h>
using namespace std;
int main()
{
	string s,c,ans;
	cin>>s>>c;
	int p1=0,p2=s.find(c);
	while(p1<s.length())     //p1小于s的总长度
	{
		if(p2==-1)     //找不到就从p1位置一直复制到最后
		{
		for(int i=p1;i<s.length();i++)
		ans+=s[i];
		break;    //跳出循环,不然是一个死循环
	    }
		for(int i=p1;i<p2;i++)
		ans+=s[i];
		p1=p2+c.length();     //p1到了删除完之后的第一个位置
		p2=s.find(c,p2+1);    //p2从原本位置的下一个位置找后面待删除的子串
	}
	cout<<ans<<endl;
}

大家可以看到,利用内置函数解法的简便性,至于find的用法,下面也是自己学到的一些解法,仅供大家参考。

删除原字符串的子串(c++内置find函数好啊)

 

上一篇:并查集


下一篇:Segment tree beats 学习笔记