严蔚敏《数据结构(C语言版)》第四章 纯C实现

本文介绍了C++中串的三种存储方式:顺序存储、堆式存储和链式存储,并提供了BF算法和KMP算法实现串的模式匹配。此外,还展示了数组抽象数据类型的实现,包括初始化、销毁、读取和赋值操作。最后,给出了三个编程题目,分别涉及统计字符、字符串反转和字符串插入操作。
摘要由CSDN通过智能技术生成


串,模式匹配

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

#define MAXLEN 255

//串的定长顺序存储
typedef struct
{
    char ch[MAXLEN + 1];
    int length;
} SString;

//串的堆式储存
typedef struct
{
    char *ch;
    int length;
} HString;

//串的链式存储结构
#define CHUNKSIZE 80
typedef struct Chunk {
    char ch[CHUNKSIZE];
    struct Chunk *next;
} Chunk;
typedef struct {
    Chunk *head, *tail;
    int length;
} LString;

void SStringCopy(SString *S, const char* strS)
{
    strcpy(S->ch, strS);
    S->length = strlen(strS);
    return;
}

int Index_BF(SString S, SString T, int pos)
{
    int i = pos, 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;
}

void test_Index_BF(void)
{
    SString S, T;
    SStringCopy(&S, "aaaaaba");
    strcpy(T.ch, "ba");
    T.length = 2;
    printf("%d\n\n", Index_BF(S, T, 1));
    return;
}
//利用已经部分匹配这个有效信息,保持i指针不回溯,
//通过修改j指针,让模式串尽量地移动到有效的位置。
int Index_KMP(SString S, SString T, int pos)
{//改进的模式匹配
    int i = pos, j = 0;
    int next[6] = {-1, 0, 0, 1, 1, 2};
    while(S.ch[i] != '\0' && T.ch[j] != '\0')
	{
		if(j == -1 || T.ch[j] == S.ch[i])
		{
			i++;
			j++;
		}
		else j = next[j];
	}
	if(T.ch[j] == '\0')
	{
		return (i-j);
	}
	return -1;
}

void test_Index_KMP(void)
{
    SString S, T;
    SStringCopy(&S, "acabaabaabcacaabc");
    SStringCopy(&T,"abaabc");
    printf("%d\n", T.length);
    printf("%d\n\n", Index_KMP(S,T, 1));
    return;
}

int main()
{
    test_Index_BF();
    return 0;
}

KMP算法

yysy,严蔚敏书上的KMP我没看懂。。。本节参考陈越姥姥的这节网课 陈越姥姥永远是我女神
请添加图片描述

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

typedef int Position;
#define NotFound -1

Position KMP(char *string, char *pattern);
void BuildMatch(char *pattern, int *match);

int main(void)
{
	char string[] = "This is a simple example";
	char pattern[] = "simple";
	Position p = KMP(string, pattern);
	if(p == NotFound)
	{
		printf("Not Found\n");
	}
	else printf("%s\n", string+p);
	return 0;
}

Position KMP(char *string, char *pattern)
{
	int n = strlen(string);
	int m = strlen(pattern);
	int s, p, *match;
	if(n < m) return NotFound;
	match = (int *)malloc(sizeof(int) * m);
	BuildMatch(pattern, match);
	s = p = 0;
	while(s<n && p<m)
	{
		if(string[s] == pattern[p])
		{
			s++;p++;
		}else if(p > 0)
		{
			p = match[p-1] + 1;
		}else s++;
	}
	
	return (p == m) ? (s-m) : NotFound;
}

void BuildMatch(char *pattern, int *match)
{
	int i, j;
	int m = strlen(pattern);
	match[0] = -1;
	for(j = 1; j < m; j++)
	{
		i = match[j-1];
		while((i>=0) && (pattern[i+1]!=pattern[j]))
			i = match[i];
		if(pattern[i+1] == pattern[j])
			match[j] = i+1;
		else match[j] = -1;
	}
}

数组的ADT

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

typedef  struct{
	int dim;
	int *dimar;
    int *data;
}Arr, *Arrp;


void InitArray(Arr *A, int n, ...)
{
	va_list sizes;
	va_start(sizes, n);
	int sumsize = 1;
	
	A->dimar = (int *)malloc(n * sizeof(int));
	A->dim = n;
	
	
	for(int idx = 0; idx < n; idx++)
	{
		int var = va_arg(sizes, int);
		if(var <= 255 && var > 0)
		{
			(A)->dimar[idx] = var;
			sumsize *= var;
		}
		else	exit(1);
	}
	(A)->data = (int *)malloc(sumsize * sizeof(int));
	va_end(sizes);
	printf("初始化成功!\n\n");
	return;
}

void DestroyArray(Arr *A)
{
	if(A->data)
	{
		free(A->data);
		free(A->dimar);
		A->dim = 0;
	}
	return;
}

void Value(Arr A, int *e, ...)
{
	va_list indexs;
	va_start(indexs, e);
	int sum = 0;
	for(int dim = 0; dim < A.dim; dim++)
	{
		int index = va_arg(indexs, int);
		for(int j = dim+1; j <= A.dim; j++)
		{
			index *= A.dimar[j];
		}
		sum += index;
	}
	va_end(indexs);
	*e = A.data[sum];
	return;
}

void Assign(Arr *A, int e, ...)
{
	va_list indexs;
	va_start(indexs, e);
	int sum = 0;
	for(int dim = 0; dim < A->dim; dim++)
	{
		int index = va_arg(indexs, int);
		for(int j = dim+1; j <= A->dim; j++)
		{
			index *= A->dimar[j];
		}
		sum += index;
	}
	va_end(indexs);
	A->data[sum] = e;
	
	return;
}


程序设计题

习题1

#include<stdio.h>
#include<ctype.h>
#include<stdlib.h>
#include<string.h>

void TongJi(char *s)
{
	int size, num[36] = {0};
	//scanf("%s", s);
	size = strlen(s);
	for(int i = 0; i < size; i++)
	{
		if(isupper(s[i]))	num[s[i]-'A']++;
		else if(isdigit(s[i]))	num['Z'-'A'+s[i]-'0'+1]++;
		else	printf("第 %d 位数据 %c 输入错误!\n", i, s[i]);
	}
	FILE *fp;
	fp = fopen("result.txt","w");
	for(int i = 0;i < 36; i++)
	{
		if(i < 26)	fprintf(fp, "%c, %d\n", 'A'+i, num[i]);
		else	fprintf(fp, "%c, %d\n", '0'+i-26, num[i]);
	}
	fclose(fp);
	return;
}
int main(void)
{
	char S[] = "ASJDHVUWIQBCYBZIQHCboIJCHGW188681YRF9YHCVV2G87232C8";
	TongJi(S);
	
	return 0;
}

习题2

#include<stdio.h>
#include<string.h>
void reverse(char* str)
{	
	char tmp = *str;//用tmp存入 字符串的第一个字符
	int len = strlen(str);//求当前字符串的长度 ps:每次递归,长度都会变化
	*str = *(str+len-1);//将'\0'的前一个元素赋给第一个
	*(str+len-1) = '\0';//将'\0'的前一个元素先赋成'\0'
	if(strlen(str)>1)//当字符串长度大于1,递归  ps:每次替换一直向中间逼近,当没有字符或只有一个字符的时候都不必继续
		reverse(str+1);//进行递归,首地址指针后移
	*(str+len-1) = tmp;//全部递归完成后,将'\0'还原成原来的中间元素	
}
int main()
{		
	char str[] = "!gnosoahoah olleH";
	reverse(str);
	printf("%s\n",str); 
	return 0;
}

习题3


int GetStrLen(char *s)
{
	int i = 0;
	while(s[i] != '\0')	i++;
	return i;
}

void insert(char *s, char *t, int pos)
{
	int s_num = GetStrLen(s);
	int t_num = GetStrLen(t);
	
	if(pos > s_num)	return;		//异常处理
	
	for(int i = s_num; i >= pos; i--)
	{
		s[i+t_num] = s[i];
	}
	for(int i = 0; i < t_num; i++)
	{
		s[i+pos] = t[i];
	}
	
	//printf("%s", s);
	return;
}

int main(void)
{
	char s[100] = "abcdef";
	char t[] = "Hello";
	insert(s, t, 8);
	
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值