严蔚敏数据结构串以及词索引表代码

 头文件String.h

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXSTRLEN 255
#define FALSE 0
#define TRUE 1
#define ERROR 0
#define OK 1
#define OVERFLOW -1
#define CHUNKSIZE 80
#define MAXLINELEN 500
#define BONOLEN 3
#define MAXWORDNUM 10
#define MAXNORWORD 6


//串的顺序存储Sequence String,0位置用来存储串长
typedef unsigned char SString[MAXSTRLEN];
typedef int Status;
void SStringAssign(SString S)
{
	printf("请输入字符串值:\n");
	gets(&(S[1]));
	S[0] = strlen(&(S[1]));
}
Status Concat_S(SString T, SString S1, SString S2)      //串S1与串S2拼接为串T,超出部分被裁
{                                                       //减
	int uncut;
	if (S1[0] + S2[0] <= MAXSTRLEN)
	{
		T[0] = S1[0] + S2[0];
		for (int i = 1; i <= S1[0]; i++)
			T[i] = S1[i];
		for (int i = S1[0] + 1; i <= S1[0] + S2[0]; i++)
			T[i] = S2[i - S1[0]];
		uncut = TRUE;
	}
	else
	{
		if (S1[0] < MAXSTRLEN)
		{
			T[0] = MAXSTRLEN;
			for (int i = 1; i <= S1[0]; i++)
				T[i] = S1[i];
			for(int i=S1[0]+1;i<=MAXSTRLEN;i++)
				T[i] = S2[i - S1[0]];
			uncut = FALSE;
		}
		else
		{
			T[0] = MAXSTRLEN;
			for (int i = 1; i <= S1[0]; i++)
				T[i] = S1[i];
			uncut = TRUE;
		}
	}
	return uncut;
}
Status SubString_S(SString Sub, SString S, int pos, int len)
{
	if (pos<1 || pos>S[0] || len<0 || len>S[0] - pos + 1)
		return ERROR;
	Sub[0] = len;
	for (int i = pos; i <= pos + len - 1; i++)
		Sub[i - pos + 1] = S[i];
	return OK;
}


//堆分配存储方式(动态分配串长)
typedef struct
{
	char* ch;
	int length;
}HString;
Status StrInsert_H(HString* S, HString T, int pos)
{
	if (pos<1 || pos>S->length + 1)
		return ERROR;
	char* p;
	p = (char*)realloc(S->ch, sizeof(char) * (S->length + T.length));
	if (!p) exit(OVERFLOW);
	S->ch = p;
	for (int i = S->length - 1; i >= pos - 1; i--)
		S->ch[i + T.length] = S->ch[i];
	for (int i = 0; i <= T.length - 1; i++)
		S->ch[pos - 1 + i] = T.ch[i];
	S->length += T.length;
	return OK;
}
Status StrAssign_H(HString* S, char* chars)
{
	int i = 0;
	for (char* c = chars; *c; ++i, ++c);
	if (!i)
	{
		S->ch = NULL;
		S->length = 0;
	}
	else
	{
		S->ch = (char*)malloc(sizeof(char) * (i + 1));
		if (!S->ch) exit(OVERFLOW);
		for (int j = 0; j <= i - 1; j++)
			S->ch[j] = chars[j];
		S->ch[i] = '\0';
		S->length = i;
	}
	return OK;
}
int StrLength_H(HString S)
{
	return S.length;
}
int StrCompare_H(HString S, HString T)
{
	for (int i = 0; i < S.length && i < T.length; i++)
		if (S.ch[i] != T.ch[i])
			return S.ch[i] - T.ch[i];
	return S.length - T.length;
}
Status ClearString_H(HString* S)
{
	if (S->ch)
	{
		free(S->ch);
		S->ch = NULL;
	}
	S->length = 0;
	return OK;
}
Status StrConcat_H(HString* T, HString S1, HString S2)
{
	if (T->ch) free(T->ch);
	T->ch = (char*)malloc(sizeof(char) * (S1.length + S2.length));
	if (!T->ch) exit(OVERFLOW);
	for (int i = 0; i <= S1.length - 1; i++)
		T->ch[i] = S1.ch[i];
	for (int i = S1.length; i <= S1.length + S2.length; i++)
		T->ch[i] = S2.ch[i - S1.length];
	T->length = S1.length + S2.length;
	return OK;
}
Status SubString_H(HString* Sub, HString S, int pos, int len)
{
	if (pos<1 || pos>S.length || len<0 || len>S.length - pos + 1)
		return ERROR;
	if (Sub->ch) free(Sub->ch);
	if (!len)
	{
		Sub->ch = NULL;
		Sub->length = 0;
	}
	else
	{
		Sub->ch = (char*)malloc(sizeof(char) * len);
		if (!Sub->ch) exit(OVERFLOW);
		for (int i = 0; i <= len - 1; i++)
			Sub->ch[i] = S.ch[pos - 1 + i];
		Sub->length = len;
	}
	return OK;
}


//串的块链存储表示(直接用链式存储导致存储密度太低,采取块链存储方式改善)
typedef struct Chunk
{
	char ch[CHUNKSIZE];
	struct Chunk* next;
}Chunk;
typedef struct
{
	Chunk* head, * tail;
	int len;
}LString;                                   //LinkString



//串的模式匹配算法
void Get_Next(SString S, int* next)
{
	int i = 1, j = 0;                   //i所指的下一位为要求next值的位置,j所指为i的next值
	next[1] = 0;                        //若j无法为i的下一位提供有用的next信息,则用j的next
	while (i < S[0])                    //继续寻找,直到找到或者j最终为0
	{
		if (j == 0 || S[i] == S[j])
		{
			i++;
			j++;
			next[i] = j;
		}
		else
			j = next[j];
	}
}
void Get_Nextval(SString S, int* nextval)
{
	int i = 1, j = 0;
	nextval[1] = 0;
	while (i < S[0])
	{
		if (j == 0 || S[i] == S[j])
		{
			i++;
			j++;
			if (S[i] != S[j])           //不等的话模式串和主串还有必要去比一下
				nextval[i] = j;
			else                        //相等的话就没必要去比了,因为绝对不相等
				nextval[i] = nextval[j];
		}
		else
			j = nextval[j];
	}
}
int Index_KMP(SString S, SString T, int pos,int* next)
{
	int i = pos, j = 1;
	while (i <= S[0] && j <= T[0])
	{
		if (j == 0 || S[i] == T[j])      //相等或者模式串无法得到next值,指针整体后移
		{
			i++;
			j++;
		}
		else                             //不相等用主串的值和模式串next值比较
			j = next[j];
	}
	if (j > T[0])                        //模式串比较完毕,返回在主串中的起始位置
		return i - T[0];
	else
		return 0;
}


//词索引表数据结构
#define MAXBOOKNUM 1000
#define MAXKEYNUM 25
typedef int ElemType;
typedef struct LNode
{
	ElemType data;
	struct LNode* next;
}LNode, *LinkList;
typedef struct
{
	HString* item;
	int last;
}WordListType;
typedef struct
{
	HString key;
	LinkList bonolist;
}IdxTermType;
typedef struct
{
	IdxTermType item[MAXKEYNUM];
	int last;
}IdxListType;

 c文件1:词索引表(说明:需要修改主函数中的文件路径,得有一个source.txt文件,会自动生成在指定文件路径下的词索引表文件destination.txt)

#include "String.h"
char* buf;                         //为buf分配MAXLINELEN+2个存储空间,一个用来存放'\0',一
WordListType wdlist;               //个用来进行溢出判定
WordListType norwdlist;
void InitIdxList(IdxListType* idxlist)
{
	idxlist->last = 1;
	idxlist->item[0].bonolist = NULL;
	char* p = (char*)malloc(sizeof(char));
	if (!p) exit(OVERFLOW);
	idxlist->item[0].key.ch = p;
	p[0] = '\0';
	idxlist->item[0].key.length = 0;
}
Status GetLine(FILE *f)
{
	fgets(buf, MAXLINELEN, f);
	if (strlen(buf) == MAXLINELEN)
		return ERROR;
	return OK;
}
void Convert_char_int(int* no, char* p)
{
	*no = 0;
	char* q = p;
	int count = 1, power = 1;
	while (*(q + 1) != '\0')
	{
		q = q + 1;
		count++;
	}
	while (count)
	{
		int i;
		switch (*q)
		{
		case '0':i = 0; break;
		case '1':i = 1; break;
		case '2':i = 2; break;
		case '3':i = 3; break;
		case '4':i = 4; break;
		case '5':i = 5; break;
		case '6':i = 6; break;
		case '7':i = 7; break;
		case '8':i = 8; break;
		default:i = 9;
		}
		*no += power * i;
		power *= 10;
		count--;
		q--;
	}
}
int NorStrCmp(WordListType norwdlist, char* p, int st, int en)
{
	char* q;
	int len = en - st + 1;
	q = (char*)malloc(sizeof(char) * (len + 1));
	if (!q) exit(OVERFLOW);
	for (int i = st; i <= en; i++)
		q[i - st] = p[i];
	q[len] = '\0';
	for (int i = 0; i < norwdlist.last; i++)
		if (strcmp(q, norwdlist.item[i].ch) == 0)
			return 1;
	return 0;
}
void GetBookNo(char* bno_s, char* p)
{
	for (int i = 0; i < BONOLEN; i++)
		bno_s[i] = *p++;
	bno_s[BONOLEN] = '\0';
}
Status ExtractKeyWord(ElemType* bno)
{
	char* bno_s;
	bno_s = (char*)malloc(sizeof(char) * (BONOLEN + 1));
	if (!bno_s) exit(OVERFLOW);
	char* p = buf;
	GetBookNo(bno_s, p);
	Convert_char_int(bno, bno_s);
	while (!((*p >= 'a' && *p <= 'z') || (*p >= 'A' && *p <= 'Z')))
		p++;
	int wpos[MAXWORDNUM];
	for (int i = 0; i < MAXWORDNUM; i++)
		wpos[i] = 0;
	char* q = p;
	int pos = 0, count = 1;
	while (*q != '\0')
	{
		if (count > MAXWORDNUM) return ERROR;
		if (*q == ' ')
		{
			wpos[count] = pos + 1;
			count++;
		}
		q++;
		pos++;
	}
	if (p[pos-1] == '\n')
		pos--;
	int i = 1;
	wdlist.last = 0;
	while (i <= count)
	{
		int st, en;
		st = wpos[i - 1];
		if (i == count)
			en = pos - 1;
		else
			en = wpos[i] - 2;
		if (!NorStrCmp(norwdlist, p, st, en))
		{
			int k = wdlist.last;
			int length = en - st + 1;
			char* r;
			r = (char*)malloc(sizeof(char) * (length + 1));
			if (!r) exit(OVERFLOW);
			wdlist.item[k].ch = r;
			strncpy(r, &(p[st]), length);
			r[length] = '\0';
			wdlist.item[k].length = length;
			wdlist.last++;
		}
		i++;
	}
	return OK;
}
void GetWord(int i, HString* wd)
{
	int length = wdlist.item[i].length;
	char* p;
	p = (char*)malloc(sizeof(char) * (length + 1));
	if (!p) exit(OVERFLOW);
	strcpy(p, wdlist.item[i].ch);
	StrAssign_H(wd, p);
}
int Locate(IdxListType* idxlist, HString wd, int* Boolean)
{
	int m, i;
	for (i = idxlist->last - 1; (m = strcmp(idxlist->item[i].key.ch, wd.ch)) > 0; i--);
	if (m == 0)  
	{
		*Boolean = TRUE;
		return i;
	}
	else
	{
		*Boolean = FALSE;
		return i + 1;
	}
}
Status InsertNewKey(IdxListType* idxlist, int i, HString wd)
{
	if (idxlist->last == MAXKEYNUM)
		return ERROR;
	for (int j = idxlist->last - 1; j >= i; --j)
		idxlist->item[j + 1] = idxlist->item[j];
	char* p;
	p = (char*)malloc(sizeof(char) * (wd.length + 1));
	if (!p) exit(OVERFLOW);
	idxlist->item[i].key.ch = p;
	StrAssign_H(&(idxlist->item[i].key), wd.ch);
	LNode* q;
	q = (LinkList)malloc(sizeof(LNode));
	if (!q) exit(OVERFLOW);
	q->next = NULL;
	idxlist->item[i].bonolist = q;
	idxlist->last++;
	return OK;
}
Status InsertBook(IdxListType* idxlist, int i, int bno)
{
	LNode* p, * q = idxlist->item[i].bonolist;
	p = (LinkList)malloc(sizeof(LNode));
	if (!p) exit(OVERFLOW);
	while (q->next)
		q = q->next;
	p->data = bno;
	q->next = p;
	p->next = NULL;
	return OK;
}
Status InsIdxList(IdxListType* idxlist, int bno)
{
	HString wd;
	for (int i = 0; i < wdlist.last; i++)
	{
		int j;
		GetWord(i, &wd);
		int bool;
		j = Locate(idxlist, wd, &bool);
		if (!bool)
			InsertNewKey(idxlist, j, wd);
		InsertBook(idxlist, j, bno);
	}
	return OK;
}
void PutText(FILE* g, IdxListType idxlist)
{
	for (int i = 1; i < idxlist.last; i++)
	{
		fputs(idxlist.item[i].key.ch, g);
		fprintf(g, "\t");
		LNode* p = idxlist.item[i].bonolist->next;
		while (p)
		{
			fprintf(g, "%-d\t", p->data);
			p = p->next;
		}
		fprintf(g, "\n");
	}
}
int main()
{
	norwdlist.last = MAXNORWORD;
	HString* nor;
	nor = (HString*)malloc(sizeof(HString) * MAXNORWORD);
	if (!nor) exit(OVERFLOW);
	norwdlist.item = nor;
	for (int i = 0; i < norwdlist.last; i++)
	{
		char* p;
		p = (char*)malloc(sizeof(char) * 4);
		if (!p) exit(OVERFLOW);
		norwdlist.item[i].ch = p;
		printf("请输入第%d个常规单词\n", i + 1);
		gets(p);
		norwdlist.item[i].length = 3;
	}
	FILE* f, * g;
	wdlist.item = (HString*)malloc(sizeof(HString) * MAXWORDNUM);
	if (!wdlist.item) exit(OVERFLOW);
	buf = (char*)malloc(sizeof(char) * (MAXLINELEN + 2));
	if (!buf) exit(OVERFLOW);
	IdxListType idxlist;
	IdxTermType* p = (IdxTermType*)malloc(sizeof(IdxTermType) * MAXKEYNUM);
	if (!p) exit(OVERFLOW);
	p = idxlist.item;
	int bno;
	if (f = fopen("C:\\Users\\14164\\Desktop\\source.txt", "r"))
		if (g = fopen("C:\\Users\\14164\\Desktop\\destination.txt", "w"))
		{
			InitIdxList(&idxlist);
			while (!feof(f))
			{
				GetLine(f);
				ExtractKeyWord(&bno);
				InsIdxList(&idxlist, bno);
			}
			PutText(g, idxlist);
		}
	return 0;
}

sorurce文件内容:

005 Computer Data Structure
010 Instroduction to Data Structure
023 Fundamentals of Data Structure
034 The Design and Analysis of Computer Algorithms
050 Introduction to Numerical Analysis
067 Numerical Analysis

 输入的常规单词:

to
and
of
The
a
an

 结果文件destination:

 c文件2:KMP算法

#include "String.h"
int main()
{
	SString S, T;
	SStringAssign(S);
	SStringAssign(T);
	int* next;
	next = (int*)malloc(sizeof(int) * (T[0] + 1));
	if (!next) exit(OVERFLOW);
	Get_Next(T, next);
	int i = Index_KMP(S, T, 1, next);
	if (i)
		printf("子串在主串中的位置为:%d", i);
	else
		printf("未找到\n");
}

结果:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值