用指针去删除字符串子串

设计一个字符串子串删除函数,并实现子串的删除。

函数定义为如下格式:

bool delStr(char *str,char *sub);

要求按照规定的格式进行代码填空。

【输入形式】

第一行输入主串

第二行输入子串

【输出形式】

输出删除子串后的结果。

【样例输入】

abcdcef

ce

【样例输出】

abcdf

【样例说明】

子串"ce"能匹配主串"abcdcef",则删除子串部分,因此得到删除后的串为"abcdf"

找错误的代码

​
#include  <stdio.h>
#include  <string.h>
#include  <stdbool.h>

#define  STRING_INIT_SIZE        100        //串初始长度

//要用到的函数全部在这里声明
int getIndex(char *str, char *sub, int pos);
bool delStr(char *str,char *sub);


int  main(){
        char  str[STRING_INIT_SIZE];        //主字符串
        char  sub[STRING_INIT_SIZE];        //要比对的子串


        printf("Please  enter  the  main  string:\n");
        gets(str);

        printf("Please  enter  a  substring:\n");
        gets(sub);



        int idx=getIndex(str,sub,0);
        printf("idx is %d",idx);


      delStr(str,sub);
      printf("str is %s\n",str);





        return  0;

}

/*
BF算法求解模式匹配
参数:str 主串的首地址,sub字串的首地址,pos起始查找位置
返回值:返回子串sub在主串str中的下标位置。
        若不存在,则返回值为-1
        其中,若sub为空串,则返回0.
例主串为:abcdce,字串为ce,起始查找位置为0,则返回4
*/

int getIndex(char *str, char *sub, int pos){
int i = pos;//开始匹配的位置
	int j = 0;
	if (pos<0 || pos>strlen(sub))
	{
		printf("匹配位置有误!");
		return 0;
	}

	if(strlen(sub)==0)
    {
        printf("empty\n");
        return 0;
    }
	while (j<=strlen(sub) && i<=strlen(str))
	{
		if (sub[j] == str[i])
		{
			++i;
			++j;
		}
		else
		{
			i++;
			j = 0;
		}

		printf("i is %d ,j is %d\n",i,j);
	  if (j== strlen(sub))
		return i-strlen(sub);


	}


		return -1;



}



/*
参数:str 主串的首地址,sub字串的首地址
返回值:返回true
功能:删除主串中匹配的子串。
*/
bool delStr(char *str,char *sub)
{

        /*获取字符串长度的几种方法
        1.使用strlen
        2.使用while(*p)
        */

        int len1=strlen(str);
        int len2=strlen(sub);

        int idx=getIndex(str,sub,0);

        //使用指针进行删除

        char*p1=str+idx;
        char*p2=str+idx+len2-1;
        //这里要减1是因为sub的第一个字符是str+idx。哎呀,不知道怎么讲。你们可以自己
        //搞个数据看看
        //确定子串的开始和结束的位置
        printf("start is %c end is %c\n",*p1,*p2);

        //开始删除
        char*p3;

        for(p3=p2+1;p3<str+len1;p3++)
        {
            *(p1)=*(p3);
            p1++;
        }


        /*
        不要采取这种删除方法
        for(;p1<p2;p1++)
        {
          *(p1)=*(p2);
        }
        大概是这个意思,就有可能是这种情况
        thesevenyears
        years

        */


         *p1='\0';






        return str;





}















​

一个大佬的代码

​

/*
BF算法求解模式匹配
参数:str 主串的首地址,sub字串的首地址,pos起始查找位置
返回值:返回子串sub在主串str中的下标位置。
        若不存在,则返回值为-1
        其中,若sub为空串,则返回0.
例主串为:abcdce,字串为ce,起始查找位置为0,则返回4
*/

int getIndex(char *str, char *sub, int pos){
    int i,flag=1;
    if(*sub=='\0')return -1;
    else{
        while(*(str+pos)!='\0'){
            if(*(str+pos)==*sub){
                for(i=1;*(sub+i)!='\0';i++){
                    if(*(str+pos+i)!=*(sub+i)){
                        flag=0;
                        break;
                    }
                }
                if(flag==1){
                    return pos;
                }
            }
            flag=1;
            pos++;
        }
        return -1;
    }
}


/*
参数:str 主串的首地址,sub字串的首地址
返回值:返回true
功能:删除主串中匹配的子串。
*/
bool delStr(char *str,char *sub){
    int index=0;
    index=getIndex(str,sub,index);
    if(index==-1)return -1;
    change(str,sub,index);
    delStr(str,sub);
    return true;

}
 
//如果需要定义其他函数,可在后面进行定义
void change(char *str,char *sub,int index)
{
    int l1,l2,i,j;
    l1=strlen(str);
    l2=strlen(sub);
    for(i=index;i<=l1-l2;i++){
    *(str+i)=*(str+i+l2);
    }
}


 

​

一个错误的代码,但是我找不到错在哪里

后面发现了,是找子字符串那里搞错了

​
int getIndex(char *str, char *sub, int pos)
{

        int i = pos;//开始匹配的位置
        int j = 0;
        if (pos<0 || pos>strlen(sub))
        {
            return -3;//输入的pos有错误
        }

        else	if(strlen(sub)==0)
        {

            return -2;//子串为零
        }

         else
           {
                while (j<=strlen(sub) && i<=strlen(str))
                {

                    if (str[i]==sub[j])
                    {
                            i++;
                            j++;
                    }

                        else
                    {

                        if(sub[j-1]!=str[i-1])
                        {
                           //ccccccccccccccccccccccccccccccccccccc,你把下标写错了
                              i++;
                        }

                        j=0;
                    }//这里要有三个判断来对付第9中情况
                    if (j== strlen(sub))
                    return i-strlen(sub);


                }
           }


                return -1;//不存在子串
}



/*
参数:str 主串的首地址,sub字串的首地址
返回值:返回true
功能:删除主串中匹配的子串。
*/
bool delStr(char *str,char *sub)
{

        /*获取字符串长度的几种方法
        1.使用strlen
        2.使用while(*p)
        */

        int len1=strlen(str);
        int len2=strlen(sub);

        int idx=getIndex(str,sub,0);
 //使用指针进行删除
         if(idx!=-2&&idx!=-1&&idx!=-3)
         {
            char*p1=str+idx;
            char*p2=str+idx+len2-1;
            //这里要减1是因为sub的第一个字符是str+idx。哎呀,不知道怎么讲。你们可以自己
            //搞个数据看看
            //确定子串的开始和结束的位置


            //开始删除
            char*p3;

            for(p3=p2+1;p3<str+len1;p3++)
            {
                *(p1)=*(p3);
                p1++;
            }
            /*
            不要采取这种删除方法
            for(;p1<p2;p1++)
            {
              *(p1)=*(p2);
            }
            大概是这个意思,就有可能是这种情况
            thesevenyears
            years

            */


             *p1='\0';
             delStr(str,sub);

         }
         else

         {
             return str;
         }
}















​

bf查找那一部分应该改成这样

​
while (i<strlen(s)&&j<strlen(t))
{
	if(s[i]==t[j]){        //比较两个字符串相同时 
		i++;
		j++;
	}
	else{                  //比较两个字符串不相同时 	
		i=i-j+1;           //i回退到原来i的下一个位置 
		j=0;               //j从0开始 
	}
 }
 if(j==strlen(t))          //t的字符比较完毕 
    return i-j;  

​

这当中可能出现的几种情况:

1.sub子串不存在
2.子串为空
3.str为空
4.正常的,只出现一次的情况
5.单个字符的情况也可以
6.子串比主串长
7.子串和主串一样(哈哈哈哈,让我找到了吧)
改变一下第一个子函数的返回值

8.好了,还有一种神奇情况就是
aaabbb
ab
太坑了
9.哎呀这里有一个bug
aabb
ab

  • 7
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值