estructura de datos de lenguaje C estructura de cadena de aprendizaje

Uno, la introducción de la cadena.

​ Una estructura de cadena es una estructura de datos compuesta por varios elementos del mismo tipo, con una marca de fin al final, una cadena es una estructura de cadena compuesta por elementos de carácter, '\0' es su marca de fin y se puede utilizar para almacenar palabras, artículos, caracteres chinos y otra información de texto.

Con el desarrollo de las computadoras y los lenguajes de programación, las cadenas se utilizan cada vez más en los programas. Las cadenas se conocen como cadenas. Las operaciones en ellas son todas las operaciones en todos los caracteres de la cadena, y el símbolo final es '\0'. , si no hay '\0' al final de la cadena, pueden ocurrir problemas como caracteres ilegibles, errores de segmento y datos sucios.

Las funciones y algoritmos que debe tener la estructura de cadenas son:

Crear: definir cadena

​ Destruir: soltar la cuerda

Vacío: eliminar todos los caracteres

Copiar: es la función strcpy

Conexión: es la función strcat

​ Comparación: es la función strcmp

Longitud: la función strlen

Cadena de consulta: la función strstr

Representación e implementación de cadenas

En general, existen dos métodos de implementación para cadenas, ambos usan tablas de secuencia, pero la memoria es diferente:

1. Use la memoria de pila para almacenar caracteres en un método de longitud fija. Una vez que la cantidad de caracteres exceda el rango de la tabla, para evitar que la memoria cruce el límite, la cadena debe ser interceptada. Solo entiéndalo .

2. Utilice caracteres de fragmentación de la memoria del montón para expandir automáticamente la memoria del montón al manipular cadenas.

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

typedef struct String
{
    
    
	char* ch;
	size_t size;
}String;

// 创建字符串
String* create_string(void)
{
    
    
	String* str = malloc(sizeof(String));
	str->ch = NULL;
	str->size = 0;
	return str;
}

// 计算长度
size_t len_string(String* str)
{
    
    
	return strlen(str->ch);
}

// 复制
void copy_string(String* str,const char* ch)
{
    
    
	size_t size = strlen(ch)+1;
	if(size > str->size)
	{
    
    
		str->ch = realloc(str->ch,size);
		str->size = size;
	}
	
	strcpy(str->ch,ch);
}

// 构建字符串
String* assign_string(const char* ch)
{
    
    
	String* str = create_string();
	copy_string(str,ch);
	return str;
}

// 判断是否是空串
bool empty_string(String* str)
{
    
    
	return NULL == str->ch;
}

// 赋值
void sav_string(String* str1,String* str2)
{
    
    
	if(str1->size < str2->size)
	{
    
    
		str1->ch = realloc(str1->ch,str2->size);
		str1->size = str2->size;
	}

	strcpy(str1->ch,str2->ch);
}

// 比较
int cmp_string(String* str1,String* str2)
{
    
    
	return strcmp(str1->ch,str2->ch);
}

// 连接
void cat_string(String* str1,String* str2)
{
    
    
	size_t size = strlen(str1->ch)+strlen(str2->ch)+1;
	if(size >= str1->size)
	{
    
    
		str1->ch = realloc(str1->ch,size);
		str1->size = size;
	}
	strcat(str1->ch,str2->ch);
}

// 清空字符串
void clear_string(String* str)
{
    
    
	free(str->ch);
	str->size = 0;
}

// 销毁字符串
void destroy_string(String* str)
{
    
    
	free(str->ch);
	free(str);
}

int main(int argc,const char* argv[])
{
    
    
	/*
	String* str1 = assign_string("hehe");
	String* str2 = create_string();
	// 浅拷贝,两个对象的ch指向了同一个字符串,当其它对象被销毁,另一个会受影响
	*str2 = *str1; // str2->ch = str1->ch; str2->len = str1->len;
	destroy_string(str1);
	puts(str2->ch);
	// 深拷贝,如果结构体中有成员是指针类型,且指向了堆内,这种结构变量不能直接赋值(浅拷贝),为了不出问题,我们需要实现深拷贝
	sav_string(str2,str1);
	destroy_string(str1);
	puts(str2->ch);
	*/
	String* str1 = assign_string("hehe");
	String* str2 = assign_string("xixi12rfaspoikjrqw;elifkj;lasejkrf;oawlikeujf;olaeirjtfasldkjf;qlwiejfa;sldkjf;qwlsekjfa;sldkfj;l");
	cat_string(str1,str2);
	puts(str1->ch);

	return 0;
}

El significado de la cadena encapsulada

1. Después de encapsular la cadena en una estructura de datos, el usuario no necesita preocuparse por el espacio de la cadena, pero esta encapsulación no tiene mucho sentido en el lenguaje C, porque es más problemático usar la operación de cadena porque de la sintaxis del lenguaje C.

2. Reescribimos la estructura de datos en lenguaje C++, porque la sintaxis de C++ hará que la estructura de datos sea más conveniente de usar.

Algoritmo para consulta de subcadena

Suponiendo que hay dos cadenas str1 y str2, la consulta de subcadena es para consultar si str2 existe en la cadena str1 y devolver la primera posición de aparición de str2 si existe. Esta operación se denomina consulta de subcadena.

char *str_str(const char *str1, const char *str2)
{
    
    
	assert(NULL != str1 && NULL != str2);
	for (int i = 0, j; '\0' != str1[i]; i++)
	{
    
    
		for (j = 0; '\0' != str2[j] && str2[j] == str1[i + j]; j++)
			;
		if ('\0' == str2[j])
			return (char *)str1 + i;
	}
	return NULL;
}

char *str_str(const char *str1, const char *str2)
{
    
    
	assert(NULL != str1 && NULL != str2);
	int i = 0, j = 0;
	while ('\0' != str1[i] && '\0' != str2[j])
	{
    
    
		if (str1[i] == str2[j])
		{
    
    
			i++;
			j++;
		}
		else
		{
    
    
			i = i - j + 1;
			j = 0;
		}
	}
	return '\0' == str2[j] ? (char *)str1 + i - j : NULL;
}

char* str_str(const char* str1,const char* str2)
{
    
    
	assert(NULL != str1 && NULL != str2);
	int sum1 = 0 , sum2 = 0 , len = 0;
	while('\0'!=str2[len]&&'\0'!=str1[len])
	{
    
    
		sum1 += str1[len];
		sum2 += str2[len++];
	}

	for(int i=len; '\0' != str1[i]; i++)
	{
    
    
		printf("%d %d\n",sum1,sum2);
		if(sum1 == sum2 && 0 == strncmp(str1+i-len,str2,len))
		{
    
    
			return (char*)str1+i-len;
		}
		else
		{
    
    
			sum1 -= str1[i-len];
			sum1 += str1[i];
		}
	}

	return NULL;
}

Supongo que te gusta

Origin blog.csdn.net/m0_62480610/article/details/126233885
Recomendado
Clasificación