GDPU 数据结构 天码行空6 字符串

一、实验目的

1、掌握串的顺序存储结构
2、掌握顺序串的基本操作方法(插入、删除等)。
3、掌握串的链式存储结构。
4、掌握链式串的几种基本操作(插入、删除等)。
5、掌握Brute-Force算法

二、实验内容

1、编写函数BFIndex(String S, int start, String T),实现Brute-Force算法,其中S为主串,start为子串在主串中的查找位置,T为子串。程序可参考书本例子。(鼓励使用KMP算法)。

2、设串采用静态数组存储结构,编写函数实现串的替换Replace(S,start,T,V),即要求在主串S中,从位置start开始查找是否存在子串T。若主串S中存在子串T,则用子串V替换子串T,且函数返回1;若主串S中不存在子串T,则函数返回0。并要求设计主函数进行测试。

三、参考代码

🌸 SString.h

#include <stdio.h>
#define MaxSize 100
typedef struct
{
	char str[MaxSize];
	int length;
} String;
int Insert(String *S, int pos, String T)
/*在串S的pos位置插入子串T*/
{
	int i;
	if(pos < 0)
	{
		printf("参数pos出错!");
		return 0;
	}
	else if(S->length + T.length > MaxSize)
	{
		printf("数组空间不足无法插入!");
		return 0;
	}
	else
	{
		for(i = S->length-1; i >= pos; i--)
			S->str[i+T.length] = S->str[i];		/*为插入做准备*/
		for(i = 0; i < T.length; i++)
			S->str[pos+i] = T.str[i];				/*插入*/
		S->length += T.length;						/*产生新的元素个数*/
		return 1;
	}
}

int Delete(String *S, int pos, int len)
{
	int i;
	if(S->length <= 0)
	{
		printf("数组中未存放字符无元素可删! \n");
		return 0;
	}
	else if(pos < 0 || len < 0 || pos+len > S->length)
	{
		printf("参数pos和len出错");
		return 0;
	}
	else
	{
		for(i = pos+len; i <= S->length-1; i++)
			S->str[i-len] = S->str[i];				/*依次前移*/
		S->length -= len;						/*产生新的长度值*/
		return 1;
	}
}

🌸 主程序

#include <bits/stdc++.h>
#include "SString.h"
#define Maxlength 100

using namespace std;

// s 为主串,start为开始的下标,t为要查找的子串
// 成功匹配则返回第一个出现在主串的子串 的 首字符下标,匹配失败返回 -1
int kmp(String s,int start,String t)
{
//	TODO 自己完成
	int res = -1;
//	预处理next数组
	int next[t.length];
	next[0] = 0;
	for(int i = 1,j = 0; i < t.length; i++)
	{
		while(j > 0 && t.str[i] != t.str[j])//不匹配的情况,往回跳
			j = next[j-1];
		
		if(t.str[i] == t.str[j])//匹配的情况,j++
			j++;
		next[i] = j;//打表
	}
	
//	kmp匹配过程
	for(int i = 0, j = 0; i < s.length; i++)
	{
		while(j > 0 && s.str[i] != t.str[j])
			j = next[j-1];
		if(s.str[i] == t.str[j] )
			j++;
		if(j == t.length)//匹配成功
		{
			res = i - j +1;
			break;
		}	
	}
	return res;
}

// S 为主串,start为开始的下标,T为要查找的子串
// 成功匹配则返回第一个出现在主串的子串 的 首字符下标,匹配失败返回 -1
int BFIndex(String S, int start, String T) {
//	TODO 自己完成
	int res = -1;//-1 表示没找到
	for(int i = 0;i < S.length; i++)
	{
		bool flag = true;
		int k = i;
		for(int j = 0; j < T.length; j++)
		{
			if(S.str[k++] != T.str[j])
			{
				flag = false;
				break;
			}
		}
		if(flag)
		{
			res = i;
			break;
		}
	}
	return res;
}

//原串:s 开始下标:start,目标串:t,替换串:v
int Replace(String *S, int start, String T, String V)
{
//	TODO 自己完成
	int idx = kmp(*S,0,T);
	if(idx == -1)//没找到
		return 0;
//	找到了,替换
	Delete(S,idx,T.length);
	Insert(S,idx,V);
	
	return 1;
}

//原串:s 开始下标:start,目标串:t,替换串:v
int myReplace(String *s, int start, String t, String v)
{
//	TODO 自己完成
	int idx = kmp(*s,0,t);
	if(idx == -1)//没找到
		return 0;
//	找到了,替换
	int len = s->length;
	int tlen = t.length;
	//原本的长度 - 替换串的长度
	int d = t.length-v.length;//d>0 后面的串左移 d 位
	if(d > 0)//后串左移
		for(int i = idx + tlen; i < len; i++)
			s->str[i-d] = s->str[i];
	else if(d < 0)//后串右移
		for(int i = len-1; i >= len - idx + tlen -1; i--)
			s->str[i-d] = s->str[i];
	s->length -= d;
	
//	将替换串放入主串中
	for(int i = idx, j =0; i < idx+v.length; i++)
		s->str[i] = v.str[j++];
	
	return 1;
}

int main(void) {

	String myString1, myString2, myString3;
	int i, start = 0;
	printf("请输入主串myString1: ");
	scanf("%s", myString1.str );
	printf("请输入子串myString2: ");
	scanf("%s", myString2.str);
	printf("请输入子串myString3: ");
	scanf("%s", myString3.str);
	myString1.length = strlen(myString1.str);
	myString2.length = strlen(myString2.str);
	myString3.length = strlen(myString3.str);
//	int res = BFIndex(myString1,0,myString2);
//	int res1 = kmp(myString1,0,myString2);
//	cout << res << " " << res1;
	
	if (Replace(&myString1, start, myString2, myString3) == 0)
		printf("不成功 ");
	else
		for (i = 0; i < myString1.length ; i++)
			printf("%c", myString1.str[i]);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值