串的运算及应用
第1关:求子串
任务描述
本关任务:实现字符串的求子串操作。
相关知识
为了完成本关任务,你需要理解:1. 求子串操作,2.字符串的顺序存储。
求子串操作
从一个字符串S的某个位置开始截取若干个连续字符,构成一个新串T。我们将S称为主串,T称为子串。这一过程称为字符串的求子串操作。
例如:已知一个字符串是“abcdefgh”,从该串的第3个字符开始截取4个连续字符,构成的子串是“cdef”。
字符串的顺序存储
#define MAXSTRLEN 255 // 串的最大长度
typedef char SString[MAXSTRLEN+1];
// 0号单元存放串的长度, 用'\0'作结束符
编程要求
在右侧编辑器中补充代码,完成SubStr函数,以实现串的求子串操作。具体要求如下:
* SubStr: 从串s的第i个字符开始截取长度为len的子串存入串t中。其中1≦i≦串s的长度, 0≦len≦ 串s的长度-i+1。
测试说明
平台会对你编写的代码进行测试,测试文件为step1/Main.cpp,可在右侧文件夹中进行查看。
输入输出格式:
输入格式: 第一行输入一个字符串 第二行输入截取的位置i和截取字符的个数len
输出格式:
若i和len超出取值范围,则输出error;
否则输出子串,末尾换行。
测试输入: abcdefgh
3 4
预期输出:
cdef
测试输入:
abcdefgh
3 8
预期输出:
error
开始你的任务吧,祝你成功!
代码实例
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "SubStr.h"
void SubStr(SString t, SString s,int i,int len)
{
int j=0;
scanf("%s",s);
scanf("%d %d",&i,&len);
if(i<=0||len>strlen(s)-i)
printf("error");
else
for(j=i;j<len+i;j++)
{
printf("%c",s[j]);
}
/********** End **********/
}
第2关:串的模式匹配之简单算法
任务描述
本关任务:实现字符串的模式匹配的简单算法(BF算法)。
相关知识
为了完成本关任务,你需要理解:1. 模式匹配,2.字符串的顺序存储。
模式匹配
子串的定位运算通常称为串的模式匹配。此运算的应用非常广泛,比如在搜索引擎、拼写检查、语言翻译、数据压缩等应用中,都需要进行串匹配。 串的模式匹配设有两个字符串S和T,设S为主串,T为子串,也称为模式。在主串S中查找与模式T相匹配的子串,如果匹配成功,确定相匹配的子串中的第一个字符在主串S中出现的位置。
例如:主串是“string”,子串是“ring”,那么子串在主串中出现的位置是3,即“ring”在“string”中出现的开始位置是3。
著名的模式匹配算法有 BF 算法和 KMP 算法。本关任务是实现 BF 算法。
字符串的顺序存储
#define MAXSTRLEN 255
// 串的最大长度
typedef char SString[MAXSTRLEN+1];
// 0号单元存放串的长度, 用'\0'作结束符
编程要求
在右侧编辑器中补充代码,完成StrIndex_BF函数,以实现串的模式匹配的 BF 算法。具体要求如下:
* StrIndex_BF: 从主串s的第pos个字符开始查找子串t。若找到,则返回子串t在主串s中第一次出现的位置,否则返回0。
测试说明
平台会对你编写的代码进行测试,测试文件为step2/Main.cpp,可在右侧文件夹中进行查看。
输入输出格式: 输入格式: 第一行输入主串 第二行输入子串 输出格式: 输出Location: #,其中#是子串在主串中的位置编号
测试输入:
sdfrt
df
预期输出:
Location: 2
测试输入:
mystring
aring
预期输出:
Location: not found!
开始你的任务吧,祝你成功!
代码实例
//串的模式匹配之简单算法 实现文件
/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "strBF.h"
int StrIndex_BF(SString s, SString t, int pos)
//从主串s的第pos个字符开始查找子串t。
//若找到,则返回子串t在主串s中第一次出现的位置,否则返回0。
{
// 请在这里补充代码,完成本关任务
/********** Begin *********/
int i,j;
i=pos;j=1;
while(i<=s[0]&&j<=t[0])
if(s[i]==t[j])
{
i++;j++;
}
else{
i=i-j+2;
j=1;
}
if(j>t[0]) return i-j+1;
else return 0;
/********** End **********/
}
第3关:串的模式匹配之KMP算法
任务描述
本关任务:实现字符串的模式匹配的 KMP 算法。。
相关知识
第2关中实现的字符串匹配的简单算法在实际应用系统中效率低,而 KMP 算法可以实现高效的字符串匹配。 假设主串为s,子串为t。为了进行 KMP 匹配,首先需要计算子串t的next数组,该功能由 GetNext 函数实现。对于abaabcac,计算出的next数组如下图:
本关涉及两个函数:
void GetNext(SString t, int next[])
//求模式串T的next值并存入next数组中
int StrIndex_KMP(SString s,SString t, int pos)
//采用KMP算法,从主串s的第pos个字符开始查找子串t第一次出现的位置
编程要求
在右侧编辑器中补充代码,完成GetNext函数,以实现串的模式匹配的 KMP 算法。具体要求如下:
* GetNext: 求模式串T的next值并存入next数组中。
测试说明
平台会对你编写的代码进行测试,测试文件为step3/Main.cpp,可在右侧文件夹中进行查看。
输入输出格式: 输入格式: 第一行输入主串 第二行输入子串 输出格式: 输出Location: #,其中#是子串在主串中的位置编号
测试输入:
stringabcedf1stringabcdef2stringabcdef3stringabcdef4stringabcdef5stringabcdef6stringabcdef7
stringabcdef7
预期输出:
Location: 79
测试输入:
stringstring1stringstring2stringstring3stringstring4stringstring5stringstring6stringstring7
stringstring8
预期输出:
Location: not found!
开始你的任务吧,祝你成功!
代码实例:
//串的模式匹配之改进算法 实现文件
//
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "strKMP.h"
/
void GetNext(SString t, int next[])
//求模式串T的next值并存入next数组中
{
// 请在这里补充代码,完成本关任务
/********** Begin *********/
int i=1,j=0;
next[1]=0;
while(i < strlen(t)){
if(j == 0 || t[i] == t[j] ){ //前缀字符等于后缀字符
++i;
++j;
next[i]=j; //将模式串由前缀位置“移动”到后缀位置
}else
j = next[j]; //字符不同,j值回溯
}
/********** End *********/
}
int StrIndex_KMP(SString s,SString t, int pos)
//采用KMP算法,从主串s的第pos个字符开始查找子串t第一次出现的位置
{
int i,j,next[MAXSTRLEN+1];
GetNext(t,next);
i=pos; j=1;
while(i<=s[0]&&j<=t[0])
if(s[i]==t[j]||j==0)
{ i++; j++; }
else j=next[j]; //模式串向右滑动
if(j>t[0]) return i-j+1; //匹配成功
else return 0; //匹配失败
}