一、实验目的
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.
分析:在进行顺序串的插入时,插入位置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在插入时也会有部分字符被舍弃
分析:在进行字符串的删除操作中,在字符串中删除从下标pos起len个字符,从pos+len开始至串尾依次向前移动,实现删除len个字符操作。
2.
分析:串的模式匹配即字串定位是一种重要的串运算。s和t是给定的两个串,从主串S的第0个字符开始查找等于子串t的过程称为模式匹配,如果在s中找到等于t的子串,则称匹配成功,函数返回t在s中首次出现的存储位置(或序号);否则,匹配失败,返回0.