漫谈数据结构(四)——串

1、什么是串

  串又称字符串,是比较常见的一个数据结构,它由0或多个字符构成,一般定义为s="abcdegf"。字符的个数称为串的长度。长度为0的串为空串,记为s="",由空格组成的串为空格串,空格也是字符,记为s=" "

  目前,随着科学技术的发展,非数值处理的情况越来越多,学好字符串的处理变得尤为重要,本文将介绍字符串处理的几个基本方法。

2、串的顺序存储

  在串的顺序存储结构中,用一组地址连续的空间,即数组来存储字符串中的字符,串中的每一个字符占据一个空间,如图所示:

串的顺序存储

2.1 创建和赋值

//创建String类型
typedef struct str{
	char *str;      //串指针 
	int length;	//串的长度	
}String; 

//赋值 
int strAssign(String * s,char *p){
	
	//获取p的长度 
	int i=0;
	while(p[i]!='\0'){
		i++;
	}
	//给str分配内存,多分配一个空间存储'\0'
	s->str = (char *)malloc(sizeof(char) * (i+1));
	//赋值
	int j;
	for(j=0;j<i;j++){
		s->str[j] = p[j]; 
	} 
	s->str[j] = '\0';
	s->length = i;

	return 1;
}  

2.2 获取串的长度

//获取串的长度
int getLength(String *s){
	return s->length;
} 

2.3 复制串

  先重新为str分配需要的内存,然后memset赋‘\0’。最后循环赋值。

//复制串,将t复制到s中 
void strCopy(String *s,String *t){
	s->str = (char*)malloc(sizeof(char) * (t->length+1));
	memset(s->str,'\0',t->length+1);
	int i;
	for(i=0;i<t->length;i++){
		s->str[i] = t->str[i];
	}
	s->length = t->length;
} 

2.4 判断两个串是否相等

//判断两个串是否相等
int strEqual(String *s1,String *s2){
	char *ss1 = s1->str;
	char *ss2 = s2->str; 

	if(s1->length != s2->length){
		return 0;
	}
	if(*ss1++ != *ss2++){
		return 0;
	}
	return 1;
} 

2.5 连接两个串

//连接两个串
int strConnect(String *s,String *p){
	int len = s->length + p->length;
	
	//临时空间 
	char *temp = (char*)malloc(sizeof(char) * (len+1));
	int i,j;
	
	//拷贝s 
	for(i=0;i<s->length;i++){
		temp[i] = s->str[i];
	}
	//拷贝p 
	for(j=0;j<p->length;j++){
		temp[j+i] = p->str[j];
	}
	temp[j+i] = '\0';
	
	//字符串指向temp 
	s->str = temp;
	s->length = len;
	
	return 1;
} 

2.6 比较两个串的大小

//比较两个串的大小 
int strCompete(String *s,String *p){
	int slen = s->length;
	int plen = p->length;
	char *s1 = s->str;
	char *p1 = p->str;
	
	//同时遍历两个字符串,有一个为空时结束循环。 
	while(*s1!='\0' && *p1!='\0'){
		// s > p 
		if(*s1 > *p1){
			return 1; 
		}
		//s < p 
		if(*s1 < *p1){
			return -1; 
		}
		s1++;
		p1++;  
	} 
	
	//两个字符串前n个字符相等时,比较长度 
	if(slen == plen){  //s=p 
		return 0;
	}
	if(slen>plen){  //s>p
		return 1;
	}
	if(slen<plen){  //s<p 
		return -1;
	}
} 

2.7 插入串

//插入串  将字符串p插入到s的指定位置上 
int strInsert(String *s,String *p,int pos){
	//位置判断
	if(pos<0||pos>s->length){
		printf("insert position error!\n");
		return;
	} 
	
	int len = s->length + p->length;
	char * temp = (char *)malloc(sizeof(char)*(len+1));
	
	int i,j;
	
	//插入 s的左边部分 
	for(i=0;i<pos;i++){
		temp[i] = s->str[i];
	} 
	//插入 p 
	for(j=0;j<p->length;j++){
		temp[j+pos] = p->str[j];
	}
 	//插入 s的右边部分 
	for(;i<s->length;i++){
		temp[j+i] = s->str[i];
	} 
	temp[j+i] = '\0';
	s->str = temp;
	s->length = len;
} 

2.8 删除指定串

//删除 
int strDelete(String *s, int pos, int length){
	//位置判断
	if(pos<0||pos>s->length){
		printf("delete position error!\n");
		return;
	} 
	
	int len = s->length - length;
	char * temp = (char*)malloc(sizeof(char)*(len+1));
	
	int i,j;
	for(i=0;i<pos;i++){
		temp[i] = s->str[i]; 
	} 
	
	j = pos+length;
	for(;j<s->length;j++){
		temp[i] = s->str[j];
		i++;
	}
	temp[i] = '\0';
	s->str = temp;
	s->length = len;
	
	return 1;
}

2.9 测试

//串的顺序存储
#include<stdio.h>
#include<stdlib.h>
#include<string.h> 
int main(){
	printf("Create String:\n");
	String * s = (String *)malloc(sizeof(String));
	char *s1 = "abcdefg";
	strAssign(s,s1); 
	puts(s->str);
	
	printf("Length = %d\n",getLength(s));
	printf("\n");

	String * p = (String *)malloc(sizeof(String));	
	char *p1 = "abc";
	strAssign(p,p1); 

	printf("Copy String %s to %s:\n",s->str,p->str);
	strCopy(p,s);
	puts(s->str);
	printf("\n");
	
	printf("是否相等:%d\n",strEqual(s,p));
	
	printf("Insert String %s to %s:\n",p->str,s->str);
	strInsert(s,p,2);
	
	puts(s->str);
	printf("\n");
	
	printf("Delete String:\n");
	strDelete(s,2,3);
	puts(s->str);
	
	return 0;
}

输出结果:
输出结果

3、串的链式存储

  串的链式存储可以使用单链表来存储字符,每一个结点存储1个字符(密度为1),有利于串的插入或删除,但它的空间利用率太低。如果一个结点存储多个字符,对字符串的操作又会变得相当麻烦,得不偿失。串的链式存储的实用率很低,使用起来也不灵活,所以,一般都是使用串的顺序存储。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值