# 结构串之字符动态顺序存储的基本原理

串是由零个或多个字符组成的有限序列,
当串中只有零个字符时称为空串,串的长度为字符的个数,
由全部字符组成的串称为主串,
在由n个字符组成的主串中,由k(k != n)个连续字符组成的串称为子串。
此处,通过堆栈与顺序表来构成了一个动态空间的字符串。

# 结构串之字符动态顺序存储的基本创建

Dynamic_SeqString_.h(头文件)
#pragma once
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#define INIT_SPACE 20
#define ADD_SPACE 3
#define DEBUG
typedef unsigned char u_char;
struct D_SeqString
{
	char* SeqString;
	int space;
	int size;
};
void Init_SeqString(struct D_SeqString* D_SS);
void Show_Menu();
int Strlen(const struct D_SeqString* D_SS);
void StrAssign(struct D_SeqString* D_SS, const char* str);
void Show_SeqString(const struct D_SeqString* D_SS);
void StrCopy(struct D_SeqString* D_SS, const char* str);
int StrCompare(const struct D_SeqString* D_SS, const char* str);
void StrConcat(struct D_SeqString* D_SS, const char* str);
void SubString(const struct D_SeqString* D_SS, char* S_str, const int index, const int s_length);
void StrInsert(struct D_SeqString* D_SS, const char* str, const int index);
int StrIndex(const struct D_SeqString* D_SS, const char* str);
void StrDelete(struct D_SeqString* D_SS, const char* str);
void StrReplace(struct D_SeqString* D_SS, const char* str, const char* r_str);
void StrClean(struct D_SeqString* D_SS);
void StrDestroy(struct D_SeqString* D_SS);
Dynamic_SS_functions.c
#include"Dynamic_SeqString_.h"
void Init_SeqString(struct D_SeqString* D_SS)
{
	assert(NULL != D_SS);
	D_SS->SeqString = (char*)malloc(sizeof(char) * INIT_SPACE);
	D_SS->space = INIT_SPACE;
	D_SS->size = 0;
}
static void Pick_malloc(struct D_SeqString* D_SS)
{
	assert(NULL != D_SS);
	D_SS->SeqString = (char*)realloc(D_SS->SeqString,sizeof(char) * (D_SS->space + ADD_SPACE));
	D_SS->space += ADD_SPACE;
}
void Show_Menu()
{
	printf("\n********************************************\n");
	printf(" [1]  StrAssign     *********[2]  Strlen   *\n");
	printf(" [3]  Show_SeqString*********[4]  StrCopy  *\n");
	printf(" [5]  StrCompare    *********[6]  StrConcat*\n");
	printf(" [7]  SubString     *********[8]  StrInsert*\n");
	printf(" [9]  StrIndex      *********[10] StrDelete*\n");
	printf(" [11] StrReplace    *********[12] StrClean *\n");
	printf(" [13] StrDestroy                           *\n");
	printf(" [0]  SystemExit                           *\n");
	printf("********************************************\n");
}
static int R_Strlen(const char* str)
{
	assert(NULL != str);
	int counting = 0;
	while (*str)
	{
		++counting;
		++str;
	}
#ifdef DEBUG
	printf("字符或字符串长度为%d\n", counting);
#endif
	return counting;
}
int Strlen(const struct D_SeqString* D_SS)
{
	assert(NULL != D_SS);
#ifdef DEBUG
	printf("字符或字符串长度为%d\n", D_SS->size);
#endif
	return D_SS->size;
}
void StrAssign(struct D_SeqString* D_SS, const char* str)
{
	assert(NULL != D_SS && NULL != str && NULL != D_SS->SeqString);
	int length_str = R_Strlen(str);
	while(length_str > D_SS->space)
		Pick_malloc(D_SS);
	while (*str)
		D_SS->SeqString[D_SS->size++] = *str++;
}
void Show_SeqString(const struct D_SeqString* D_SS)
{
	assert(NULL != D_SS && NULL != D_SS->SeqString);
	int i = 0;
	for (i = 0; i < D_SS->size; ++i)
	{
		printf("%c", D_SS->SeqString[i]);
	}
}
void StrCopy(struct D_SeqString* D_SS, const char* str)
{
	assert(NULL != D_SS && NULL != str && NULL != D_SS->SeqString);
	int length_str = R_Strlen(str);
	
	D_SS->size = 0;
	if (length_str + ADD_SPACE < D_SS->space)
	{
		D_SS->space = length_str + ADD_SPACE;
		D_SS->SeqString = (char*)realloc(D_SS->SeqString, sizeof(char) * D_SS->space);
	}
	while (*str)
		D_SS->SeqString[D_SS->size++] = *str++;
}
int StrCompare(const struct D_SeqString* D_SS, const char* str)
{
	assert(NULL != D_SS && NULL != str && NULL != D_SS->SeqString);
	
	char* DSS_P = D_SS->SeqString;
	while (*str)
	{
		if (*(DSS_P) > *str)
		{
			#ifdef DEBUG
				printf("较大于输入的字符串");
			#endif
			return 1;
		}
		else if (*(DSS_P) < *str)
		{
			#ifdef DEBUG
				printf("较小于输入的字符串");
			#endif
			return -1;
		}
		++DSS_P;
		++str;
	}
#ifdef DEBUG
	printf("等于输入的字符串");
#endif
	return 0;
}
void StrConcat(struct D_SeqString* D_SS, const char* str)
{
	assert(NULL != D_SS && NULL != str && NULL != D_SS->SeqString);
	int length_str = R_Strlen(str);
	
	while(length_str + D_SS->size > D_SS->space)
		Pick_malloc(D_SS);
	while (*str)
		D_SS->SeqString[D_SS->size++] = *str++;
}
void SubString(const struct D_SeqString* D_SS, char* S_str, const int index, const int s_length)
{
	assert(NULL != D_SS && NULL != S_str && NULL != D_SS->SeqString);
	
	if (index <= 0 || index > D_SS->size)
		return;
	else
	{
		int i_s = 0;
		int i_ix = index - 1;
		while (i_s < s_length)
		{
			*S_str++ = D_SS->SeqString[i_ix++];
			++i_s;
		}
		*S_str = '\0';
	}
}
void StrInsert(struct D_SeqString* D_SS, const char* str, const int index)
{
	assert(NULL != D_SS && NULL != str && NULL != D_SS->SeqString);
	if (index <= 0 || index > D_SS->size)
		return;
	else
	{
		int length_str = R_Strlen(str);
		int M_index = index - 1;
		int S_board = index - 1;
		while (D_SS->size + length_str > D_SS->space)
			Pick_malloc(D_SS);
		while (length_str)
		{
			int i = 0;
			for (i = D_SS->size; i > S_board; --i)
				D_SS->SeqString[i] = D_SS->SeqString[i - 1];
			--length_str;
			++D_SS->size;
			++S_board;
		}
		while (*str)
			D_SS->SeqString[M_index++] = *str++;
	}
}
int StrIndex(const struct D_SeqString* D_SS, const char* str)
{
	assert(NULL != D_SS && NULL != str && NULL != D_SS->SeqString);
	int length_DSS = D_SS->size;
	int counting = 0;
	char* P_DSS = D_SS->SeqString;
	while (length_DSS)
	{
		const char* P_str = str;
		++counting;
		if (*str == *P_DSS)
		{
			int flag = 1;
			char* P_P_DSS = P_DSS;
			while (*P_str)
			{
				if (*P_str++ != *P_P_DSS++)
				{
					flag = 0;
					break;
				}
			}
			if (flag)
				return counting;
		}
		--length_DSS;
		++P_DSS;
	}
	return 0;
}
void StrDelete(struct D_SeqString* D_SS, const char* str)
{
	assert(NULL != D_SS && NULL != str && NULL != D_SS->SeqString);
	
	int index = 0;
	int length_str = R_Strlen(str);
	while (index = StrIndex(D_SS, str))
	{
		int i = 0;
		int M_time = length_str;
		while (M_time)
		{
			for (i = index - 1; i < D_SS->size; ++i)
				D_SS->SeqString[i] = D_SS->SeqString[i + 1];
			--D_SS->size;
			--M_time;
		}
	}
}
void StrReplace(struct D_SeqString* D_SS, const char* str, const char* r_str)
{
	assert(NULL != D_SS && NULL != str && NULL != r_str && NULL != D_SS->SeqString);
	int index = 0;
	int length_str = R_Strlen(str);
	int length_rs = R_Strlen(r_str);
	while (index = StrIndex(D_SS, str))
	{
		const char* P_rs = r_str;
		int M_time = length_rs - length_str;
		while (length_rs + D_SS->size > D_SS->space)
			Pick_malloc(D_SS);
		while (M_time)
		{
			int i = 0;
			for (i = D_SS->size; i > index - 1; --i)
			{
				D_SS->SeqString[i] = D_SS->SeqString[i - 1];
			}
			++D_SS->size;
			--M_time;
		}
		while (*P_rs)
		{
			D_SS->SeqString[index++ - 1] = *P_rs++;
		}
	}
}
void StrClean(struct D_SeqString* D_SS)
{
	assert(NULL != D_SS);
	D_SS->size = 0;
	D_SS->space = INIT_SPACE;
}
void StrDestroy(struct D_SeqString* D_SS)
{
	assert(NULL != D_SS && NULL != D_SS->SeqString);
	free(D_SS->SeqString);
	D_SS->SeqString = NULL;
}
Dynamic_SS_main.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"Dynamic_SeqString_.h"
int main()
{
	struct D_SeqString D_SS;
	char str[INIT_SPACE];
	char r_str[INIT_SPACE];
	char S_str[INIT_SPACE];
	int option = 0;
	int index = 0;
	int s_length = 0;
	Init_SeqString(&D_SS);
	Show_Menu();
	while (printf("选择是>"), scanf("%d", &option), printf("\n"), option)
	{
		getchar();
		switch (option)
		{
		case 1:
			printf("输入的字符串>");
			scanf("%s", str);
			StrAssign(&D_SS, str);
			break;
		case 2:
			Strlen(&D_SS);
			break;
		case 3:
			Show_SeqString(&D_SS);
			break;
		case 4:
			printf("拷贝的字符串>");
			scanf("%s", str);
			StrCopy(&D_SS, str);
			break;
		case 5:
			printf("需比较的字符串>");
			scanf("%s", str);
			StrCompare(&D_SS, str);
			break;
		case 6:
			printf("需接入的字符串>");
			scanf("%s", str);
			StrConcat(&D_SS, str);
			break;
		case 7:
			printf("字符字串起始位置与长度>");
			scanf("%d %d", &index, &s_length);
			SubString(&D_SS, S_str, index, s_length);
			printf("%s", S_str);
			break;
		case 8:
			printf("插入字符与位置>");
			scanf("%s %d", str, &index);
			StrInsert(&D_SS, str, index);
			break;
		case 9:
			printf("寻找的字符或字符串>");
			scanf("%s", str);
			if (index = StrIndex(&D_SS, str))
				printf("字符或字符串起始位置为%d", StrIndex(&D_SS, str));
			else
				printf("字符或字符串起始位置未找到");
			break;
		case 10:
			printf("需删除的字符或字符串>");
			scanf("%s", str);
			StrDelete(&D_SS, str);
			break;
		case 11:
			printf("被替换的字符与替换字符>");
			scanf("%s %s", str, r_str);
			StrReplace(&D_SS, str, r_str);
			break;
		case 12:
			StrClean(&D_SS);
			break;
		case 13:
			StrDestroy(&D_SS);
			break;
		default: printf("不在选择范围内\n");
		}
		Show_Menu();
	}
	StrDestroy(&D_SS);
	printf("已退出\n");
	return 0;
}