BF算法和KMP算法C++实现

这里写自定义目录标题

BF算法和KMP算法C++实现

KMP算法主要思想:
利用查找目标串上一次比较时的信息,以提高搜索速度。

完整代码:

// BF & KMP
#include <cstdlib>
#include <iostream>
#include <string>
#include<ctime>
using namespace std;
// 函数结果状态代码
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
#define MAXLEN 100
#define CHUNKSIZE 80 
//Status 是函数的类型,其值是函数结果状态代码
typedef int Status;

#define MAXSIZE 100
typedef int ElemType;

typedef struct {
	ElemType* elem;
	int length;
} SqList; //顺序表类型

Status InitList_Sq(SqList& L) {         //构造一个空的顺序表L
	L.elem = new ElemType[MAXSIZE];     //为顺序表分配空间
	if (!L.elem) exit(OVERFLOW);        //储存分配失败
	L.length = 0;                       //空表长度为0
	return OK;
}

void DestroyList(SqList& L) {
	if (L.elem) delete L.elem; //释放存储空间
}

void ClearList(SqList& L) {
	L.length = 0; //将线性表的长度置为0
}

int GetLength(SqList L) {
	return (L.length);
}

int IsEmpty(SqList L) {
	if (L.length == 0) return 1;
	else return 0;
}

int GetElem(SqList L, int i, ElemType& e) {
	if (i<1 || i>L.length) return ERROR;
	// 判断i值是否合理,若不合理,返回ERROR
	e = L.elem[i-1]; //第i-1的单元存储着第i个数据
	return OK;
}

// 按值查找
int LocateElem(SqList L, ElemType e) {
	//在线性表L中查找值为e的数据元素,返回其序号
	for (int i = 0; i < L.length; i++)
		if (L.elem[i] == e) return i + 1; //查找成功,返回序号
	return 0;//查找失败,返回0
}

// 插入算法
Status ListInsert_Sq(SqList& L, int i, ElemType e) {
	if (i<1 || i>L.length + 1)return ERROR;  //i值不合法
	if (L.length == MAXSIZE)return ERROR;    //当前存储空间已满
	for (int j = L.length - 1; j >= i - 1; j--)
		L.elem[j + 1] = L.elem[j];           //插入位置及之后的元素后移
	L.elem[i-1] = e;                       //将新元素e放入第i个位置
	L.length++;                              //表长增1
	return OK;
}

// 顺序存储结构
typedef struct {
	char ch[MAXLEN + 1]; // 存储串的一维数组
	int length; // 串的当前长度
}SString;


// 块链存储结构
typedef struct Chunk {
	char ch[CHUNKSIZE];
	struct Chunk* next;
}Chunk;

typedef struct {
	Chunk* head, * tail; // 串的头指针和尾指针
	int curlen; // 串的当前长度
}LString;


Status StrAssign(SString &S,string s) {
	int s_length;
	s_length = s.length();
	for (int i = 1; i <= s_length; i++) {
		S.ch[i] = s[i-1];
	};
	S.length = s_length;
	return OK;
}

// 串的模式匹配算法
// BF 暴力,时间效率低
int Index_BF(SString S, SString T,int pos) {
	int i = pos; int j = 1;
	while (i <= S.length && j <= T.length) {
		if (S.ch[i] == T.ch[j]) {
			++i;
			++j;
		}// 主串和子串依次匹配下一个字符
		else {
			i = i - j + 2; j = 1;
		}// 主串、子串指针回溯重新开始下一次匹配
	}
	if (j >= T.length)return i - T.length;
	else return 0;
}

// KMP 速度快,理解难
int Index_KMP(SString S, SString T, int pos,SqList next) {
	int i = pos; int j = 1;
	while (i <= S.length && j <= T.length) {
		if (j == 0 || S.ch[i] == T.ch[j]) {
			i++; j++;
		}
		else {
			GetElem(next, j, j);
		}
	}
	if (j > T.length)return i - T.length; /*匹配成功*/
	else return 0; /*返回匹配不成功标志*/
}
int get_next(SString T,SqList &next) {
	ListInsert_Sq(next, 1, 0);
	int i = 1;int j = 0;
	while (i < T.length) {
		// abcabcd
		if (j == 0 || T.ch[i] == T.ch[j]) {
			++i; ++j;
			ListInsert_Sq(next, i, j);
		}
		
		else {
			GetElem(next, j, j);
			
		};
		int e;
		GetElem(next, i, e);
	}
	cout << endl;
	return OK;
}



int main(){

	SString S;
	SString T;
	string s = "bcabcdbcabcdefefcabcbcabcdefabcdefaabcabcabcdefg";
	string t = "abcabcd";
	clock_t startTime;
	clock_t endTime;
	int pos = 1;
	StrAssign(S, s);
	StrAssign(T, t);
	SqList next;
	InitList_Sq(next);

	get_next(T, next);

	cout << "next值:" << endl;
	for (int i = 1; i <= t.length(); i++){
		int e;
		GetElem(next, i, e);
		cout << e;
	}
	cout << endl;
	startTime = clock();
	int index_KMP = Index_KMP(S, T, pos, next);
	endTime = clock();
	
	double KMP_time = endTime - startTime;

	startTime = clock();
	int index_BF = Index_BF(S, T, pos);
	endTime = clock();
	double BF_time = endTime - startTime;
	cout << "计算完毕" << endl;
	cout << "index_BF: " << index_BF << endl;
	cout << "time_BF: " << BF_time << endl;

	cout << "index_KMP: " << index_KMP << endl;
	cout << "time_KMP: " << KMP_time << endl;

	system("pause");
	return 0;
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值