数据结构实验报告:串

一、实验目的

1.掌握串的实现

2.掌握串的应用

3.熟悉堆串和块链串

二、实验环境

windows 10、Visual C++6.0

三、实验内容

1.编写程序,实现串的插入和删除算法

#include <stdio.h>
#include <stdlib.h>
#define MAXLEN 40
typedef struct {          /*串结构定义*/
    char ch[MAXLEN];
    int len;
}SString;

void createstring(SString *s)
{
	int i,j;
	char c;
	printf("请输入要建立的串的长度:");
	scanf("%d",&j);
	for(i=0; i<j; i++)
	{
		printf("请输入串的第%d个字符:",i+1);
		fflush(stdin);
		scanf("%c",&c);
		s->ch[i] = c;
	}
	s->len = j;
}

void output(SString *s)
{
	int i;
	for (i=0;i<s->len;i++)
		printf("%c   ",s->ch[i]);
	printf("\n");
}

int StrInsert(SString *s, int pos, SString t)
/*在串s中下标为pos的字符之前插入串t */
{
	int i;
	if (pos<0 || pos>s->len) /*插入位置不合法*/
		return(0); 
	if (s->len + t.len<=MAXLEN) /*插入后串长≤MAXLEN*/
	{
		for (i=s->len + t.len-1;i>=t.len + pos;i--)
			s->ch[i]=s->ch[i-t.len];
		for (i=0;i<t.len;i++) 
			s->ch[i+pos]=t.ch[i];
		s->len=s->len+t.len;
	}
	else
	{
		if (pos+t.len<=MAXLEN) /*插入后串长>MAXLEN,但串t的字符序列可以全部插入*/
		{
			for (i=MAXLEN-1;i>t.len+pos-1;i--) 
				s->ch[i]=s->ch[i-t.len];
			for (i=0;i<t.len;i++)
				s->ch[i+pos]=t.ch[i];
			s->len=MAXLEN;
		}
		else /*插入后串长>MAXLEN,并且串t的部分字符也要舍弃*/
		{ 
			for (i=0;i<MAXLEN-pos;i++)
				s->ch[i+pos]=t.ch[i];
			s->len=MAXLEN;
		}
		return(1);
	}
}

		
void main()
{
	SString *str1;
	SString  str2;
	int i,j,k,pos;
	int flag=0;
	str1 = (SString *)malloc(sizeof(SString));
	str1->len = 0;
	printf("建立字符串1:\n");
	createstring(str1);
	printf("建立字符串2:\n");
	createstring(&str2);
	printf("请输入要插入的位置:");
	scanf("%d",&pos);
	flag=StrInsert(str1,pos,str2);
	if(flag == 0)
		printf("插入操作失败!");
	else
	{
		printf("插入后串为:\n");
		output(str1);
	}

}
#include<stdio.h>
#include<stdlib.h>

#define MAXLEN 40
typedef struct {          /*串结构定义*/
    char ch[MAXLEN];
    int len;
}SString;

void createstring(SString *s)
{
	int i,j;
	char c;
	printf("请输入要建立的串的长度:");
	scanf("%d",&j);
	for(i=0; i<j; i++)
	{
		printf("请输入串的第%d个字符:",i+1);
		fflush(stdin);
		scanf("%c",&c);
		s->ch[i] = c;
	}
	s->len = j;
}

void output(SString *s)
{
	int i;
	for (i=0;i<s->len;i++)
		printf("%c   ",s->ch[i]);
	printf("\n");
}

int StrDelete(SString *s, int pos, int len)
/*在串s中删除从下标pos起len个字符*/
{ 
	int i;
	if (pos<0 || pos>(s->len-len))/*删除参数不合法*/
		return(0); 
	for (i=pos+len;i<s->len;i++)
		s->ch[i-len]=s->ch[i]; /*从pos+len开始至串尾依次向前移动,实现删除len个字符*/
	s->len=s->len - len; /*s串长减len*/
	return(1);
}

void main()
{
	SString *str1;
	int j,pos;
	int flag=0;
	str1 = (SString *)malloc(sizeof(SString));
	str1->len = 0;
	printf("建立字符串:\n");
	createstring(str1);
	printf("请输入删除位置和长度:\n");
	fflush(stdin);
	scanf("%d,%d",&pos,&j);
	flag=StrDelete(str1,pos,j);
	if(flag == 0)
		printf("删除操作失败!");
	else
	{
		printf("删除后串为:\n");
		output(str1);
	}
	
}

//----------------------------------串的插入和删除

2.编写程序,实现串的模式匹配问题

#include "stdio.h"
#include "stdlib.h"

/*链式存储方式下的模式匹配,每个字符用一结点表示*/

typedef struct Block{
	char   ch;
	struct Block   *next;
}Block;

typedef struct {
	Block   *head;
	Block   *tail;
	int     len;
}BLString;

int StrAssign(BLString *s, char *tval)
/*将字符串常量tval的值赋给块链串s*/
{
	Block *p,*q;
	int len, i=0;

	if (s->head != NULL) {
		/*释放原来存储在S中的结点空间*/
		p = s->head;
		while (p != NULL) {
			q = p->next;
			free(p);
			p = q;
		}

		s->head = s->tail = NULL;
	}

	/*计算字符串长度*/
	while (tval[i] != '\0') i++;

	len = i;s->len = len;

	if (len > 0) {
		p = (Block *)malloc(sizeof(Block));
		if (p == NULL) return 1;
		s->head = s->tail = q = p;
		i=0;

		while (i < len) {
			p = (Block *)malloc(sizeof(Block));
			if (p == NULL) return 1;
			q->next = p;q = p;

			//printf("\nCopying %c",tval[i]);
			p->ch = tval[i++];
		}
	}

	q->next = NULL;s->tail = q;

	return 0;
}

int StrDelete(BLString *s, int pos, int len)
{
	/*在串s中删除从下标pos起len个字符 */
	int i,j;
	Block *p,*q,*r;

	if (pos<0 || pos>(s->len - len)) return 1;

	i = 0;
	p = s->head;
	while(i<pos){
		p = p->next;
		i++;
	}

	q = p;

	j = 0;
	p = p->next;
	while (j<len) {
		r = p->next;
		//printf("\ndeleting %c",p->ch);
		free(p);
		p = r;
		j++;
	}

	q->next = p;
	s->len = s->len - len;
	if (q->next == NULL) {
		s->tail = q;
	}

	return 0;
}

Block *StrIndex(BLString *s, BLString *t)
/*求子串t在主串s中第一次出现的位置指针*/
{
	Block *p = NULL;
	Block *q = NULL;
	Block *tmp = NULL;
	int j;

	if (t->len == 0) return NULL;

	p = s->head->next;
	q = t->head->next;
	tmp = p;
	j = 0;
	while(p != NULL && q != NULL)
	{
		if (p->ch == q->ch) {
			p = p->next;
			q = q->next;
		}
		else
		{
			p = tmp->next;
			tmp = p;
			j++;
			q = t->head->next;
		}
	}

	if ( q == NULL) {
		printf("\nFound!=%c in position %d\n",tmp->ch,j);
		return tmp;
	}
	else return NULL;
}

int main()
{
	static BLString s,t;
	char str1[80],str2[80];

	printf("请输入主串s的内容:");
	scanf("%s",str1);
	printf("\n请输入子串t的内容:");
	scanf("%s",str2);

	StrAssign(&s,str1);
	StrAssign(&t,str2);

	Block *pos = StrIndex(&s,&t);
	if (pos == NULL) {
		printf("\nString not found!\n");
	}

	//释放空间
	StrDelete(&s,0,s.len);
	StrDelete(&t,0,t.len);
	return 0;
}
//----------------------------------串的模式匹配

四、实验结果与分析

 

1.

8f0aa3fbbb4942b7869a50f770aa647d.png

分析:在进行顺序串的插入时,插入位置pos将串分为两部分(字符串1长度为LA和字符串 2长度为LB)及插入的位置长度为LC,则串插入前的AB变成ACB,由于是顺序串,出入会引起元素的移动。会有三中情况:

        (1)插入后长(LA+LC+LB)<=MAXLEN,则B后移LC个元素位置,再将C插入;

        (2)插入后长>MAXLEN且pos+LC<=MAXLEN,则B后移时会有部分字符被舍弃;

        插入后长>MAXLEN且pos+LC>MAXLEN,则B的全部字符被舍弃(不需后移),并且C在插入时也会有部分字符被舍弃

0898678b0f594fe2afab5165f0f94c10.png

分析:在进行字符串的删除操作中,在字符串中删除从下标pos起len个字符,从pos+len开始至串尾依次向前移动,实现删除len个字符操作。

2.

515ce91228fe4431ab6acf8cb9c0675b.png

分析:串的模式匹配即字串定位是一种重要的串运算。s和t是给定的两个串,从主串S的第0个字符开始查找等于子串t的过程称为模式匹配,如果在s中找到等于t的子串,则称匹配成功,函数返回t在s中首次出现的存储位置(或序号);否则,匹配失败,返回0.

 

  • 8
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值