第1关:子串插入
任务描述
本关任务:编写一个将子串插入到主串的第i(i>=1)个位置的函数,当参数错误时返回0,成功插入时返回1。
相关知识
为了完成本关任务,你需要掌握:1.串的定义,2.串的存储结构。
串的定义
串(string)是零个或多个字符组成的有限序列。一般记为 s="a1a2… an" (n≥0) 其中,s是串的名,用双引号括起来的字符序列是串的值。 串的长度:串中字符的个数n。 子串和主串:串中任意个连续的字符组成的子序列称为该串的子串。包含子串的串相应地称为主串。
串的存储结构
串的顺序存储方式类似于线性表的顺序存储方式,其存储结构用C语言描述为: typedef struct {
char data[MaxSize]; //存放串字符,最多MaxSize个 int length; //串的实际长度 }SqString; //定义顺序串类型
如何在主串指定位置插入子串?
在主串中插入时,插入位置将主串分为两个部分(假设为A和B)及待插入部分(假设为C,长度为len),串从插入前的AB变为ACB。插入操作的具体实现方法:将B向后移动len个位置,然后插入子串C。
编程要求
请仔细阅读右侧代码,结合相关知识,在Begin-End区域内进行代码补充,完成子串插入函数的功能,插入成功返回1,插入位置错误,返回0。
测试说明
平台会对你编写的代码进行测试:
测试输入: abcd
123
2
预期输出: a123bcd
测试输入: 1234567
aaa
9
预期输出: fail!
开始你的任务吧,祝你成功!
#include <stdio.h>
#define MaxSize 100 //串中最多字符个数
typedef struct
{ char data[MaxSize]; //存放串字符
int length; //存放串的实际长度
} SqString; //顺序串类型
void Assign(SqString &s,char str[])
{ int i=0;
while (str[i]!='\0') //遍历str的所有字符
{ s.data[i]=str[i];
i++;
}
s.length=i;
}
void DispStr(SqString s)
{ int i;
for (i=0;i<s.length;i++)
printf("%c",s.data[i]);
printf("\n");
}
int InsStr(SqString &s,int i,SqString t)
{
/********** Begin **********/
if(i < 0 || i > t.length + 1)
{
return 0;
}
int j;
SqString temp;
temp.length = 0;
for (j = 0; j < i - 1; j++)
{
temp.data[j] = s.data[j];
temp.length++;
}
for (j = 0; j < t.length; j++)
{
temp.data[j + i - 1] = t.data[j];
temp.length++;
}
for (j = i - 1; j < s.length; j++)
{
temp.data[j + t.length] = s.data[j];
temp.length++;
}
s = temp;
return 1;
/********** End **********/
}
int main()
{ SqString s,t;
int i,n;
char ss[100],tt[100];
scanf("%s",ss);
Assign(s,ss);
scanf("%s",tt);
Assign(t,tt);
scanf("%d",&i);
n=InsStr(s,i,t);
if(n>0) DispStr(s);
else printf("fail!\n");
return 0;
}
第2关:子串删除
任务描述
本关任务:将主串中从第i(1<=i<=n)个位置开始的j(j>0)个字符删除掉,当参数错误时返回0,成功插入时返回1。
相关知识
串的删除操作就是在串s中删除i开始的j个字符,然后将后面的字符向前移动。删除成功返回1,否则返回0.
如何删除一个子串
将s的第i+j位置之后的字符,依次前移j个位置,并修改s的长度。
编程要求
根据提示,在右侧编辑器补充代码。
测试说明
平台会对你编写的代码进行测试:
测试输入: abcdefg
2
4
预期输出: afg
测试输入: abcd
0 2
; 预期输出: fail.
开始你的任务吧,祝你成功!
#include <stdio.h>
#define MaxSize 100
typedef struct
{ char data[MaxSize];
int length;
} SqString;
void Assign(SqString &s,char str[])
{ int i=0;
while (str[i]!='\0')
{ s.data[i]=str[i];
i++;
}
s.length=i;
}
void DispStr(SqString s)
{ int i;
for (i=0;i<s.length;i++)
printf("%c",s.data[i]);
printf("\n");
}
int DelStr(SqString &s,int i,int j)
{
/********** Begin **********/
if (i <= 0 || i > s.length)
{
return 0;
}
SqString temp;
temp.length = 0;
int k;
for (k = 0; k < i - 1; k++)
{
temp.data[k] = s.data[k];
}
for (k = i + j - 1; k < s.length; k++)
{
temp.data[k - j] = s.data[k];
}
temp.length = s.length - j;
s = temp;
return 1;
/********** End **********/
}
int main()
{ SqString s;
char ss[100];
int i,j,t;
scanf("%s",ss);
scanf("%d%d",&i,&j);
Assign(s,ss);
t=DelStr(s,i,j);
if(i>0) DispStr(s);
else printf("fail.\n");
return 0;
}
第3关:子串定位
任务描述
本关任务:搜索某一段文字中,是否有一个目标子串。
相关知识
这是串的一种重要操作,很多软件,若有“编辑”菜单项的话,则其中必有“查找”子菜单项。 首先,回忆一下串匹配(查找)的定义: INDEX (S, T, pos) 初始条件:串S和T存在,T是非空串,1≤pos≤StrLength(S)。 操作结果:若主串S中存在和串T值相同的子串, 则返回它在主串S中第pos个字符之后第一次出现的位置; 否则函数值为0。 如果想搜索某一段文字中的目标子串,最有效的方法是遍历文本中的所有字符来在每个位置检查其是否是目标。
如何求出最大值
模式匹配算法基本思想是:从目标串s="s0s1s2…sn-1"的第i个字符起与模式串t="t0t1t2…tm-1"进行比较。即从 j=0 起比较 s[i+j] 与 t[j],若相等,则在主串 s 中存在以i 为起始位置匹配成功的可能性,继续向后比较,直至与t串中最后一个字符相等为止。否则,改从s串第i个字符的下一个字符起重新开始进行下一轮的“匹配”,即将串t向后滑动一位(i增1,j退回至0),重新开始新一轮的匹配,直至串t中的每个字符依次和串s中的一个连续的字符序列相等,则称模式匹配成功,此时串t的第1个字符在串s中的位置就是t在s中的位置,否则模式匹配失败。
编程要求
请仔细阅读右侧代码,结合相关知识,在Begin-End区域内进行代码补充。 输入 一个待搜索的子串 输出 该子串第一次出现在主串中的位置,如果没有该子串,返回-1。
测试说明
平台会对你编写的代码进行测试:
测试输入: 123456
456
预期输出: 4
测试输入: 1234567
223
; 预期输出: fail
开始你的任务吧,祝你成功!
#include <stdio.h>
#define MaxSize 100
typedef struct
{
char data[MaxSize];
int length;
} SqString;
void Assign(SqString& s, char str[])
{
int i = 0;
while (str[i] != '\0')
{
s.data[i] = str[i];
i++;
}
s.length = i;
}
void DispStr(SqString s)
{
int i;
for (i = 0; i < s.length; i++)
printf("%c", s.data[i]);
printf("\n");
}
int Index(SqString s, SqString t)
{
/********** Begin **********/
int i = 0, j = 0;
while (i < s.length && j < t.length)
{
if (s.data[i] == t.data[j])
{
i++;
j++;
if (j >= t.length)
{
return (i - j + 1);
break;
}
}
else
{
i++;
j = 0;
}
}
if (i >= s.length)
{
return -1;
}
/********** End **********/
}
int main()
{
SqString s, t;
char ss[100], tt[100];
int i;
scanf("%s", ss);
Assign(s, ss);
scanf("%s", tt);
Assign(t, tt);
i = Index(s, t);
if (i != -1) printf("%d\n", i);
else printf("fail\n");
return 0;
}
第4关:子串替换
任务描述
本关任务:将主串中所有出现的子串均替换成另一个子串,当主串中没有子串时返回主串;否则返回替换后的结果串。
相关知识
如果想将某一段文字中的目标子串替换成另一个子串,有效的方法是先查找该目标子串的位置,将其删除掉,然后再在该位置插入另一个子串,如此重复遍历文本中的所有该子串的位置全部替换掉。
如何求出最大值
可以调用子串定位,子串删除和子串插入三个操作来完成。 循环在主串中查找该子串,找到了就先删除子串,然后在该位置插入替换子串。直到主串中所有的子串都替换完。
编程要求
请仔细阅读右侧代码,结合相关知识,在Begin-End区域内进行代码补充。 输入 主串s=”123452389”,子串s1=”23”,替换子串s2=”abc” 输出 删除了该子串的主字符串 s=”1abc45abc89”
测试说明
平台会对你编写的代码进行测试:
测试输入: 123452389
23
abc
预期输出: 1abc45abc89
测试输入: 123123123
2
0
预期输出: 103103103
开始你的任务吧,祝你成功!
#include <stdio.h>
# include <string.h>
#define MaxSize 100
typedef struct
{ char data[MaxSize];
int length;
} SqString;
void Assign(SqString &s,char str[])//写入
{ int i=0;
while (str[i]!='\0')
{ s.data[i]=str[i];
i++;
}
s.length=i;
}
void DispStr(SqString s)//输出
{ int i;
for (i=0;i<s.length;i++)
printf("%c",s.data[i]);
printf("\n");
}
int Index(SqString s,SqString t)//定位
{ int i=0,j=0;
while (i<s.length && j<t.length)
{ if (s.data[i]==t.data[j])
{ i++;
j++;
}
else
{ i=i-j+1;
j=0;
}
}
if (j>=t.length)
return i-t.length+1;
else
return -1;
}
int InsStr(SqString &s,int i,SqString t)//插入
{ int j;
if (i<1 || i>s.length+1)
return 0;
else
{ for (j=s.length-1;j>=i-1;j--)
s.data[j+t.length]=s.data[j];
for (j=0;j<t.length;j++)
s.data[i+j-1]=t.data[j];
s.length=s.length+t.length;
return 1;
}
}
int DelStr(SqString &s,int i,int j)//删除
{ int k;
if (i<1 || i>s.length || j<1 || i+j>s.length+1)
return 0;
else
{ for(k=i+j-1;k<s.length;k++)
s.data[k-j]=s.data[k];
s.length=s.length-j;
return 1;
}
}
SqString RepStrAll(SqString s,SqString s1,SqString s2)
{
/**************begin***************/
int i;//返回值
i = Index(s, s1);//定位
while (i > 0)
{
DelStr(s, i, s1.length);//删除
InsStr(s, i, s2);//插入
i = Index(s, s1);//再查找
}
return s;
/**************end***************/
}
int main()
{ SqString s,s1,s2,t;
char ss[100],ss1[100],ss2[100];
scanf("%s",ss);
scanf("%s",ss1);
scanf("%s",ss2);
Assign(s,ss);
Assign(s1,ss1);
Assign(s2,ss2);
t=RepStrAll(s,s1,s2);
DispStr(t);
return 0;
}