串
一般常考顺序存储结构,即数组存储,这里将数组索引为0的位置置空,从索引为1地方存数据,也是王道书上的实现方法
朴素匹配(时间复杂度为O(mn),可以改进为KMP算法)
设i为主串索引,j是匹配串索引
- 从两个串第一个位置开始匹配(索引为1):
-
- 如果匹配成功则i++并且j++
-
- 如果匹配失败则令i=i-j+2, j=1
- 如果j越界则匹配成功,返回匹配成功的主串索引 = i - 匹配串.length
- 如果i越界,j未越界则表明寻找不到匹配串
CODE
#define MAXSIZE 255 // 这个定义后面没有分号
#include <stdio.h>
// 1.1 串的基本操作
// 顺序存储: 长度、char数组
// 在王道书上,数组第一位空着不存,所以索引从1开始,这里也这样
typedef struct {
int len;
char data[MAXSIZE];
}SString;
// 初始化
void init(SString &s) {
s.len = 0;
}
// 顺序存储(使用堆分配,即第二章动态数组)
// 初始化:
// HString str;
// str.len = 0;
// str.pt = (*char)malloc(MAXSIZE*sizeof(char));
typedef struct {
char *pt;
int len;
}HString;
// 链式存储(仅作了解)
// 一个节点存放一个字符数组
typedef struct Nodes{
char data[4];
Nodes *next;
}Nodes, *LString;
// =============================================
// 给空字符串赋值, 返回赋值后的长度
// (1) 获得字符串长度
// (2) 如果容量够,对字符串进行遍历,注意从1处开始遍历
int strAssign(char *str,SString &string){
int strlen = 0;
while (str[strlen] != '\0'){
strlen++;
}
if(string.len==0 && MAXSIZE-1>strlen) { // 第0个位置空着不存
for (int i = 1; i <= strlen; i++){
string.data[i] = str[i-1];
}
string.len = strlen;
return string.len;
}
return 0;
}
// 打印字符串
void showStr(SString string){
for(int i = 1; i <= string.len; i++){
printf("%c\t",string.data[i]);
}
printf("\n");
}
// =============================================
// 朴素匹配字符串(可以改进为KMP算法)
// 返回匹配成功子串的首地址
// (1) 从位置为1处开始匹配
// + 匹配成功,两个子串继续匹配,i++,j++
// + 匹配失败,让i回溯,让j为1
// (2) j越界大于其匹配串长度,匹配成功
// i越界大于主串长度,匹配失败
int originSearch(SString S, SString T){
int i=1,j = 1; // int i,j=1是错误初始化,这样i是随机值
while (i <= S.len && j <= T.len){
if(S.data[i] == T.data[j]){
i++;j++;
}else{
j = 1;
i = i - j + 2;
}
}
if (j > T.len){
return i-T.len;
}
return 0;
}
int main() {
SString string;
init(string);
strAssign("abcdefg",string);
SString T;
init(T);
strAssign("cde",T);
showStr(string);
showStr(T);
printf("place=%d", originSearch(string,T));
return 0;
}