【Datenstruktur】 Speicherstruktur und grundlegende Operationen von Strings (sequenzielle Strings fester Länge, Heap-Strings, Blockchain-Strings) (Sprache C)

1. Das Grundkonzept von Strings

String (String) ist eine endliche Folge von null oder mehr Zeichen. Aufgezeichnet als S = 'a1a2...an' (n>0),
wobei S der Name der Zeichenfolge ist, die in einfache Anführungszeichen eingeschlossene Zeichenfolge der Wert der Zeichenfolge ist und jedes ai (1<=i<= n) kann ein Buchstabe, Zahlen oder andere Zeichen sein. n ist die Anzahl der Zeichen in der Zeichenfolge, die als Länge der Zeichenfolge bezeichnet wird, und die Zeichenfolge, wenn n = 0, wird als leere Zeichenfolge bezeichnet.

Teilzeichenfolge : Eine Teilfolge, die aus beliebigen aufeinanderfolgenden Zeichen in einer Zeichenfolge besteht, wird als Teilzeichenfolge der Zeichenfolge bezeichnet.
Hauptstring : Der String, der Teilstrings enthält, wird als Hauptstring bezeichnet.
Die Position des Teilstrings im Hauptstring : Normalerweise wird die Seriennummer eines Zeichens im String als Position des Zeichens im String bezeichnet. Die Position des Teilstrings im Hauptstring wird durch die Position des ersten Zeichens des Teilstrings im Hauptstring dargestellt.
String-Gleichheit : Zwei Strings werden genau dann als gleich bezeichnet, wenn ihre Werte gleich sind, d. h. nur wenn die Längen der beiden Strings gleich sind und die Zeichen an jeder entsprechenden Position gleich sind.

Ein String stellt eine bestimmte lineare Tabelle dar. Die logische Struktur eines Strings ist einer linearen Tabelle sehr ähnlich, ihre Besonderheit liegt lediglich darin, dass das Datenobjekt eines Strings auf einen Zeichensatz beschränkt ist. Übliche Implementierungsmethoden umfassen sequentielle Strings mit fester Länge, Heap-Strings und Blockchain-Strings.

Zeichenfolgenmusterabgleich (einfacher Musterabgleichalgorithmus, KMP-Algorithmus) siehe: https://blog.csdn.net/weixin_51450101/article/details/122684649

2. Sequentielle Zeichenfolge fester Länge

Die Zeichenfolge fester Länge ist als statischer Strukturtyp konzipiert, der eine Gruppe von Speichereinheiten mit fortlaufenden Adressen verwendet, um die Zeichenfolge der Zeichenfolge zu speichern.

2.1 Code + Hinweise

# include<stdio.h>
# define MAXLEN 40
# define TRUE 1
# define FALSE 0

/*定长顺序串*/
/*定长顺序串的存储结构*/
typedef struct {
    
    
	char ch[MAXLEN];
	int len;			//字符串长度
}SString;

/*定长顺序串初始化*/
void StrInit(SString* S) {
    
    
	S->len = 0;
}

/*定长顺序串的创建*/
void StrCreate(SString* S) {
    
    
	int n, i;
	printf("字符串长度为:");
	scanf("%d", &n);
	printf("请输入字符串:");
	for (i = 0; i < n; i++) {
    
    
		scanf(" %c", &(S->ch[i]));
	}
	S->len = n;
}

/*插入*/
int StrInsert(SString* S, int pos, SString *t) {
    
    
//在串S中下标为pos的字符之前插入串t
	int i;
	if (pos < 0 || pos > S->len)				//插入位置不合法
		return FALSE;
	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];		//位置pos后的字符串后移
		for (i = 0; i < t->len; i++)
			S->ch[i + pos] = t->ch[i];			//将t串插入
		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 TRUE;
}

/*顺序串删除*/
int StrDelete(SString* S, int pos, int n) {
    
    
//在串S中删除从下标pos起n个字符
	int i;
	if (pos<0 || pos>(S->len - n))				//删除位置不合法
		return FALSE;
	for (i = pos + n; i < S->len; i++)
		S->ch[i - n] = S->ch[i];				//从pos+n开始至尾串依次向前移动,实现删除n个字符
	S->len = S->len - n;
	return TRUE;
}

/*串比较函数*/
int StrCompare(SString* S, SString* t) {
    
    
//若串S和t相等返回0;若S>t返回正数;S<t返回负数
	int i;
	for (i = 0; i < S->len && i < t->len; i++) {
    
    
		if (S->ch[i] != t->ch[i])
			return (S->ch[i] - t->ch[i]);
	}
	return (S->len - t->len);
}

/*定长顺序串的输出*/
void Display(SString* S) {
    
    
	int i;
	for (i = 0; i < S->len; i++)
		printf("%c", S->ch[i]);
	printf("\n");
}

int main() {
    
    
	SString S, t;
	int pos, n;
	printf("--------串的创建--------\n");	//创建
	StrInit(&S);
	StrCreate(&S);
	printf("创建的字符串:");
	Display(&S);

	printf("\n--------串的插入--------\n");	//插入
	StrInit(&t);
	StrCreate(&t);
	printf("要插入位置为:");
	scanf("%d", &pos);
	StrInsert(&S, pos, &t);
	printf("插入后字符串:");
	Display(&S);

	printf("\n--------串的删除--------\n");	//删除
	printf("删除的位置及字符个数:");
	scanf("%d%d", &pos, &n);
	StrDelete(&S, pos - 1, n);
	printf("删除后字符串:");
	Display(&S);

	printf("\n--------串的比较--------\n");	//比较
	if (StrCompare(&S, &t) == 0)
		printf("串S = 串t\n");
	else if(StrCompare(&S, &t) > 0)
		printf("串S > 串t\n");
	else
		printf("串S < 串t\n");
	return 0;
}

2.2 Laufergebnisse

Laufendes Ergebnis einer sequenziellen Zeichenfolge mit fester Länge

3. Haufen

Eine Zeichenkette umfasst zwei Teile, einen Zeichenkettennamen und einen Zeichenkettenwert, und der Zeichenkettenwert wird unter Verwendung eines Heap-Zeichenkettenspeicherverfahrens gespeichert, und der Zeichenkettenname wird in einer Symboltabelle gespeichert.
Heap-String-Speicherverfahren : Die Zeichen im String werden sequentiell in einer Gruppe von Speichereinheiten mit kontinuierlichen Adressen gespeichert, aber ihr Speicherplatz wird während der Programmausführung dynamisch zugewiesen. Das System verwendet einen Speicherplatz mit fortlaufenden Adressen und einer großen Kapazität als verfügbaren Platz für Zeichenfolgen.Immer wenn eine neue Zeichenfolge erstellt wird, weist das System einen Speicherplatz mitder gleichen Größe wie die Zeichenfolgenlänge aus diesem Speicherplatz zum Speichernder Zeichenfolge des Neuen zu Zeichenfolge.Wert.
Zeichenfolgennamen-Symboltabelle : Das Speicherabbild aller Zeichenfolgennamen stellt eine Symboltabelle dar. Mit dieser Struktur kann eine entsprechende Beziehung zwischen Zeichenfolgennamen und Zeichenfolgenwerten hergestellt werden, die als Speicherabbild der Zeichenfolgennamen bezeichnet wird.

3.1 Code + Hinweise

# include<stdio.h>
# include<malloc.h>
# define TRUE 1
# define FALSE 0

/*堆串*/
/*堆串的存储结构*/
typedef struct {
    
    
	char* ch;									//ch域指示串的起始地址
	int len;
}HString;

/*初始化*/
void StrInit(HString* s) {
    
    
	s->ch = NULL;
	s->len = 0;
}

/*堆串赋值*/
int StrAssign(HString* s, char* tval) {
    
    
//将字符串常量tval的值赋给堆串s
	int len = 0, i = 0;
	if (s->ch != NULL)
		free(s->ch);
	while (tval[i] != '\0')
		i++;
	len = i;
	if (len) {
    
    
		s->ch = (char*)malloc(len);				//申请空间
		if (s->ch == NULL)
			return FALSE;
		for (i = 0; i < len; i++)				//将字符串常量tval的值赋给堆串s
			s->ch[i] = tval[i];
	}
	else
		s->ch = NULL;
	s->len = len;
	return TRUE;
}

/*堆串插入*/
int StrInsert(HString* s, int pos, HString* t) {
    
    
//在串s中下标为pos的字符之前插入串t
	int i;
	char* temp;
	if (pos < 0 || pos > s->len || s->len == 0)	//插入位置不合法
		return FALSE;
	temp = (char*)malloc(s->len + t->len);
	if (temp == NULL)
		return FALSE;
	for (i = 0; i < pos; i++)
		temp[i] = s->ch[i];						//串s前半段插入temp
	for (i = 0; i < t->len; i++)
		temp[i + pos] = t->ch[i];				//串t插入temp
	for (i = pos; i < s->len; i++)
		temp[i + t->len] = s->ch[i];			//串s后半段插入temp
	s->len += t->len;
	free(s->ch);
	s->ch = temp;								//temp赋给串s
	return TRUE;
}

/*堆串删除*/
int StrDelete(HString* s, int pos, int n) {
    
    
	int i;
	char* temp;
	if (pos < 0 || pos>s->len - n)				//删除位置不合法
		return FALSE;
	temp = (char*)malloc(s->len - n);
	for (i = 0; i < pos; i++)
		temp[i] = s->ch[i];
	for (i = pos + n; i < s->len; i++)
		temp[i - n] = s->ch[i];
	s->len -= n;
	free(s->ch);
	s->ch = temp;
	return TRUE;
}

/*堆串输出*/
void Display(HString* s) {
    
    
	int i;
	if (s->len == 0)
		printf("空串!\n");
	else {
    
    
		for (i = 0; i < s->len; i++) {
    
    
			printf("%c", s->ch[i]);
		}
		printf("\n");
	}
}

int main() {
    
    
	int pos, n;
	HString s, t;
	char tval_s[6] = {
    
     'a','b','c','d','e' };
	char tval_t[4] = {
    
     'q','w','r' };
	printf("------堆串赋值------\n");			//赋值
	StrInit(&s);
	StrAssign(&s, tval_s);						//串s赋值
	printf("串s为:");
	Display(&s);
	StrInit(&t);
	StrAssign(&t, tval_t);						//串t赋值
	printf("串t为:");
	Display(&t);

	printf("\n------堆串插入------\n");			//插入
	printf("插入位置:");
	scanf("%d", &pos);
	StrInsert(&s, pos - 1, &t);
	printf("插入后为:");
	Display(&s);

	printf("\n------堆串删除------\n");			//删除
	printf("删除位置和个数:");
	scanf("%d%d", &pos, &n);
	StrDelete(&s, pos - 1, n);
	printf("删除后为:");
	Display(&s);
	return 0;
}

3.2 Laufergebnisse

Ergebnisse des Heap-Laufs

4. Blockkettenzeichenfolge

Eine verknüpfte Liste speichert einen Zeichenfolgenwert, und jeder Knoten kann entweder ein Zeichen oder mehrere Zeichen speichern. Jeder Knoten wird als Block bezeichnet, und die gesamte verknüpfte Liste wird als Blockchain-Struktur bezeichnet.
Speicherstruktur des Blockchain-Strings

/*块链串的存储结构*/
# define BLOCK_SIZE 4	//每结点存放字符个数为4

typedef struct Block {
    
    
	char ch[BLOCK_SIZE];
	struct Block* next;
}Block;

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

Die Knoten in der verketteten Liste sind in zwei Bereiche unterteilt, Daten und Link. Die Größe des Knotens bezieht sich auf die Anzahl der in der Datendomäne gespeicherten Zeichen, und die Größe der Kettendomäne bezieht sich auf die Anzahl der in der Verbindung belegten Zeichen Domain.
Speicherdichte = von String-Werten belegte Speicherbits/Strings tatsächlich zugeordnete Speicherbits. Je kleiner die Speicherdichte des Strings ist, desto bequemer ist die Berechnung und Verarbeitung, aber desto größer ist der belegte Speicherplatz.

Referenz: Geng Guohua „Datenstruktur – beschrieben in C-Sprache (zweite Ausgabe)“

Weitere Datenstrukturinhalte finden Sie in meiner Spalte "Datenstruktur" : https://blog.csdn.net/weixin_51450101/category_11514538.html?spm=1001.2014.3001.5482

Ich denke du magst

Origin blog.csdn.net/weixin_51450101/article/details/122668121
Empfohlen
Rangfolge