串的基本概念

串(string)(或字符串)是由零个或多个字符组成的有限序列,一般记为:

s='a1a2...an'(n>=0)

串的基本操作

串的逻辑结构与线性表极为相似,区别仅在于串的数据对象约束为字符集 。然而串的操作与线性表有很大的差别。在线性表基本操作中,大多以单个元素作为操作对象;而在串的基本操作中通常以“串的整体”作为操作对象。

例如在串中查找某个子串、求取某一个字串、在串的某个位置插入一个字串以及删除一个字串等。

常用的c语言标准库字符串函数,像strcpy()、strcmp(),strcat(),substr(),strlen()等。


串的基本运算

    对于串的基本运算,很多高级语言均提供了相应的运算符或标准的库函数来实现。
为叙述方便,先定义几个相关的变量:
    char s1[20]="dir/bin/appl",s2[20]="file.asm",s3[30],*p;
    int result;
    下面以C语言中串运算介绍串的基本运算 

1、求串长
        int strlen(char *s);//求串s的长度
    【例】printf("%d",strlen(s1)); //输出s1的串长12


2、串复制
    char *strcpy(char *to,*from);//将from串复制到to串中,并返回to开始处指针
    【例】strcpy(s3,s1);  //s3="dir/bin/appl",s1串不变




3、联接
    char *strcat(char *to,char *from);//将from串复制到to串的末尾,
                                      //并返回to串开始处的指针
    【例】strcat(s3,"/"); //s3="dir/bin/appl/"
            strcat(s3,s2); //s3="dir/bin/appl/file.asm"


4、串比较
    int strcmp(char *s1,char *s2);//比较s1和s2的大小,
   //当s1<s2、s1>s2和s1=s2时,分别返回小于0、大于0和等于0的值 
    【例】result=strcmp("baker","Baker");  //result>0
            result=strcmp("12","12");  //result=0
            result=strcmp("Joe","joseph")  //result<0


5、字符定位
    char *strchr(char *s,char c);//找c在字符串s中第一次出现的位置,
                                 //若找到,则返回该位置,否则返回NULL
    【例】p=strchr(s2,'.'); //p指向"file"之后的位置
      if(p) strcpy(p,".cpp"); //s2="file.cpp" 


  注意:
     ①上述操作是最基本的,其中后 4个操作还有变种形式:strncpy,strncath和strnchr。
     ②其它的串操作见C的<string.h>。在不同的高级语言中,对串运算的种类及符号都不尽相同
     ③其余的串操作一般可由这些基本操作组合而成


动态存储分配的顺序串


     顺序串的字符数组空间可使用C语言的malloc和free等动态存储管理函数,来根据实际需要动态地分配和释放。
     这样定义的顺序串类型亦有两种形式。
(1)较简单的定义
     typedef char *string; //C中的串库<string.h>相当于使用此类型定义串

(2)复杂定义

typedef struct
{
char *ch; //若是非空串,则按串长分配存储区,否则ch为空串
int length; //串长度 
}HString;


串的顺序储存操作【参见动画演示


下面是具体的实现:

/*
*HString.cpp
*author:xwz
*compiler:Dev-C++
*2017-7-3
*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define ERROR 	-1	
#define OVERFLOW 0
#define OK 	0
#define TRUE 0
#define FALSE -1
typedef int Status;
typedef struct
{
	char *ch;					//若是非空串,则按串长分配存储区,否则ch为空串	
	int length;					//串长度 
}HString;

void init_string(HString *T)
{ 
	//初始化串
	T->ch = NULL;
	T->length = 0;
}

Status StrAssign(HString &T,char *s)
{
	//生成一个其值等于常量s的串T
	int i,j=0;
	char *p;
	
	if(T.ch) free(T.ch);		
	for(i=0,p=s; *p ; ++i,++p);						//求s的长度 i 
	
	if(!i)											//若s为空串
	{
		T.ch = NULL;
		T.length = 0;
	}
	else
	{
		if(!(T.ch = (char*)malloc(i*sizeof(char))))				//为串分配s串度的空间
			exit(OVERFLOW);
		while(T.ch[j] = s[j++]);
		T.length = i; 
	} 
	return OK;
} 

int StrLength(const HString &T)
{	//返回串T的长度 
	return T.length;
}

Status StrCopy(HString &T,const HString &S)
{
	//将串S复制给串T
	int j=0;
	if(T.ch) free(T.ch);
	if(S.length)
	{
		if(!(T.ch = (char*)malloc(S.length*sizeof(char))))
			exit(OVERFLOW);
		while(*(T.ch+j) = *(S.ch+j++));     
		T.length = S.length;
	}				
	else
	{
		T.ch = NULL;
		T.length = 0;
	}
	return TRUE;
} 

Status StrInsert(HString &S,int pos,const HString &T) 
{
	//1<=pos<=StrLength(S) + 1 ,在串S的第pos个字符之前插入串T
	int i,j; 
	if(pos<1 || pos > StrLength(S) + 1)
		return ERROR;
	if(T.length)
	{	
		//重新为串S分配空间
		if(!(S.ch = (char*)realloc(S.ch,(S.length+T.length)*sizeof(char))))			 
			exit(OVERFLOW);
			
		//为串T腾出空间
		for(i=S.length-1; i>=pos-1; --i) 
			S.ch[i+T.length] = S.ch[i];
			
		//将串T插入至串S中的pos处 
		for(i=pos-1,j=0; i<=pos+T.length-1 && j<T.length; ++i,++j)
			S.ch[i] = T.ch[j]; 
			
		S.length += T.length;
		S.ch[S.length] = '\0';
	} 
	return OK;	 
}

int StrCompare(const HString &T,const HString &S)
{
	//两串相比,若T>S返回 >0,T<S 返回 <0 ,T=S 返回0 
	int i;
	for(i=0; i<T.length && i<S.length; ++i)
	{
		if(T.ch[i] != S.ch[i]) 
		return T.ch[i] - S.ch[i];			//ASCAL 值 
	}
	return T.length - S.length; 
}

Status Concat(HString &T,const HString &S1,const HString &S2) 
{
	//用T返回由S1和S2连接而成的新串
	int i,j;
	if(T.ch) free(T.ch);
	if(S1.length && S2.length)
	{
		if(!(T.ch=(char*)malloc((S1.length+S2.length)*sizeof(char))))
			exit(OVERFLOW);
		for(i=0;i<S1.length;++i)
			T.ch[i] = S1.ch[i];
		for(j=0;i<S1.length+S2.length && j<S2.length;++j,++i)
			T.ch[i] = S2.ch[j];
		T.length = S1.length + S2.length;
		T.ch[T.length] = '\0';
	} 
	return TRUE;
} 

Status SubString(HString &Sub,const HString &S,int pos,int len)
{
	//用Sub返回S从pos位置开始长度为len的子串 
	int i,j;
	
	if(pos<1 || pos > S.length+1 || len<1 || len>S.length-pos+1)
		return ERROR;
		
	if(Sub.ch) free(Sub.ch);
	if(!len)
	{
		Sub.ch = NULL;
		Sub.length = 0;
	}
	
	if(S.length)
	{
		if(!(Sub.ch = (char*)malloc(len*sizeof(char))))
			exit(OVERFLOW);
		for(j=0,i=pos-1; j<len && i<pos+len-1;++i,++j)
			 Sub.ch[j]=S.ch[i]; 
		
		Sub.length = len;
		Sub.ch[len] = '\0';
	}

	return TRUE;
}

void destory_string(HString &T)
{	
	//销毁串 
	if(T.ch)
	{
		T.length = 0;
		free(T.ch);
	}
}

int Index(const HString &S,const HString &T,int pos)
{
	//T为非空串,若主串S中第pos个字符之后存在与 T相等的子串
	//则返回第一个这样的字串在S中的位置,否则返回FALSE
	HString sub;
	init_string(&sub);
	int sLen = S.length,tLen = T.length,i;
	
	if(pos>0)
	{
		i = pos;
		while(i <= sLen-tLen+1)
		{
		   	SubString(sub,S,i,tLen);
			if(StrCompare(T,sub)!=0) 
				++i;
			else 
			{
				destory_string(sub);
				return i;
			} 
		}
	}
	destory_string(sub); 
	return 0; 
}

Status Replace(HString &S, const HString &T,const HString & V)
{
	//用V替换主串S中出现的所有与T相等的不重叠的字符串
	HString sub;
	init_string(&sub);
	int sLen = S.length,tLen = T.length,i=1,j,k;
	
	while(i <= sLen-tLen+1)
	{
		//依次找出与V长度相等的串 
	   	SubString(sub,S,i,tLen);
		if(StrCompare(T,sub)==0) 
		{
			j=i-1;
			k=0;
			while((S.ch[j++] = V.ch[k++]) && (k<V.length))
				;
		} 
		++i;
	}
	
	destory_string(sub); 
	return TRUE; 
}

Status Trimed(HString &T)
{
	//去除串T中的空格 
		
	int j,i=0,k=0;
	if(T.length)
	{
		while(T.ch[i++] != T.ch[T.length])					//T.ch[i] != '\0' 
		{
				if(T.ch[i] == ' ')
				{
					for(j=i; j<T.length; ++j)
						T.ch[j] = T.ch[j+1];
					++k;							//记录空格数 
				}
				//连续两个或两个以上的空格 
				if(T.ch[i] == ' ')
					Trimed(T);
		}
		T.length -= k;
	}	
	return TRUE; 
} 

bool StrEmpty(const HString &S)
{
	return S.length == 0;
}

Status StrDelete(HString &S,int pos,int len)
{
	//从字符串中删除第pos个字符起长度为len的子串 
	int i,j;
	if(pos<1 || pos > S.length+1 || len<1 || len>S.length-pos+1)
		return ERROR;
	for(i=pos-1; i<S.length; ++i)
		S.ch[i] = S.ch[i+len];
	S.length -= len;
} 

int main()
{
	HString T,S,S2;
	char str1[] = "helloppllo";
	char str2[] = "llo";
	char str3[] = "wsa";
	char str4[] = "hello wor  ld";
	
	init_string(&T);
	StrAssign(T,str1);
//	printf("%s\n",T.ch);
	
	init_string(&S);
	StrAssign(S,str2);
//	StrCopy(T,S);
//	StrInsert(S,2,T);
//	printf("%s\n",S.ch);
	
//	int j=StrCompare(T,S);
//	printf("%d",j);
	
//	Concat(S2,T,S);
//	printf("%s\n",S2.ch);
	
//	HString Sub;
	
//	init_string(&Sub);
//	
//
//	
//	SubString(Sub,T,2,2);	 
//	printf("%s",Sub.ch);
//
//	destory_string(Sub);

//	int i = Index(T,S,1); 
//	printf("%d\n",i);
	
	
//	init_string(&S2);
//	StrAssign(S2,str3);
//	Replace(T,S,S2);			//T="helloppllo",S="llo" ,S2="wsa";
//	printf("%s\n",T.ch);
	
//	printf("T = %s,T.length = %d\n",T.ch,T.length);
//	Trimed(T);
//	printf("T = %s,T.length = %d\n",T.ch,T.length);
	
	StrDelete(T,3,2);
	printf("T = %s,T.length = %d\n",T.ch,T.length);
//	destory_string(S2);
	destory_string(T);
	destory_string(S);
	
	getchar();
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值