串的基本概念

串(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;
}



發佈了64 篇原創文章 · 獲贊 141 · 訪問量 21萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章