设计一个字符串子串删除函数,并实现子串的删除。
函数定义为如下格式:
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