資料結構(C實現)------- 串,資料結構-------
字串(簡稱串),可以將其看作是種特殊的線性表,其特殊性在於線性表的資料元素的類型總是字元性,字串的資料對象約束為字元集。
串是由0個或多個字元組成的有限序列。一般記作:s = "s1 s2 s3 .... sn",,其中,s是串名,用雙引號括起來的字元序列稱為串的值,si(1<=i <= n)稱為串的元素,可以是字母,數字或其他字元,是構成串的基本單位,字元的個數n稱為串的長度.
串中的幾個術語:
1. 空串: 由0個字元組成的串稱為空白串,空串不包含任何字元,其長度為0。
2. 子串: 串中任意個連續的字元組成的子序列稱為該串的子串,空串是任何串的子串。
3. 主串: 包含子串的串相應的稱為主串。
4. 子串在主串的位置:通常稱字元在序列中的序號為該字元在串的位置,子串在主串中的位置則以子串的第一個字元在主串中的位置來表示。
5. 兩串相等:若且唯若兩個串的長度相等,並且各個對應位置的字元都相等時才相等。
串的表示: 1. 串的順序儲存表示:
串的順序儲存結構簡稱為順序串,順序串中的字元序列被順序地存放在一組連續的儲存單元中,主要有三種實現順序串的方式,分別如下:
(1) 定長字元數組
在串的順序儲存結構中,按照預定義的大小,為每個定義的串變數分配一個固定大小的儲存區,描述如下:
//定長字元數組描述#define MAXSIZE 100typedef char SString[MAXSIZE];
(2) 帶串長的字元數組
//帶串長的字元數組#define MAXSIZE 100typedef struct{char ch[MAXSIZE];int length;}SqString;
(3) 串的堆分配(即動態數組)儲存描述
//串的堆分配儲存描述typedef struct{char *ch; //若是非空串,則按串長分配儲存區,否則,ch為NULLint length; //串長度}HString;
2.串的鏈式儲存表示:
和線性表的鏈式儲存結構相類似,也可以採用鏈表方法儲存串值,有以下兩個方法:
(1)串的鏈式結構類型描述:
//串的鏈式儲存結構描述typedef struct node{char str;struct node *next;}CNode,*LinkString;
(2)串的塊鏈儲存類型描述:
//串的塊鏈結構類型描述#define NODESIZE 3typedef struct node{char ch[NODESIZE];struct node *next;}SNode,*LinkStr;LinkStr head;
3.串的索引儲存表示:
串也可以用索引的方式來表示,有以下兩種方法:
(1)串的帶長度的索引表:
//帶長度的索引表#define MAXSIZE 100typedef struct{char name[MAXSIZE];int length;char *startadr;}LSNode;
(2) 串的帶末指標的索引表:
//串的帶末指標的索引表#define MAXSIZE 100typedef struct{char name[MAXSIZE];int length;char *startadr;char *endadr;}ENode;
以上介紹了三種儲存結構來表示串,每一種儲存結構又可以用幾種不同的方式來描述串,那麼,串的實現方法相應的也有多種,但不管有多少種,串的基本操作原理不變,變的只是處理的方式,所以也沒有必要將所有方式都學會,只要會一種即可,這裡就實現其中最常用動態數組來描述串,並以此種方式來實現口串的各種操作。
基本操作:
這裡所有的基本操作都是建立在上述的用動態數組,即堆結構來描述串的前提下的,直接給出代碼,裡面有注釋。
//串的堆分配儲存描述typedef struct{char *ch; //若是非空串,則按串長分配儲存區,否則,ch為NULLint length; //串長度}HString;//初始化一個空的順序串void Str_Init(HString *S){S->ch = NULL;S->length = 0;}//清空順序串void Str_Clear(HString *S){if(S->ch){free(S->ch);Str_Init(S);}}//判斷順序串是否為空白int Str_IsEmpty(HString *S){return S->length == 0;}//求取串的長度int Str_GetLength(HString *S){return S->length;}//順序串的賦值void Str_Assign(HString *S,char *chars){int i = 0,j;char *c = chars;//先清空順序串S Str_Clear(S);//求得賦值串的長度while(*c){i++;c++;}//如果賦值串的長度大於0,則進行賦值if(i > 0){S->ch = (char*)malloc(3*sizeof(char));for(j = 0;j < i;j++){S->ch[j] = chars[j];}S->length = i;}}//順序串的複製,將T複製到Svoid Str_Copy(HString *S,HString *T){int i;//先清空順序串S Str_Clear(S); S->length = T->length; if(S->length){S->ch = (char *)malloc(sizeof(char)*S->length);for(i = 0;i < S->length;i++)S->ch[i] = T->ch[i];}}//順序串的串連,將T串連到S後 void Str_Concat(HString *S,HString *T){//臨時存放S串 HString temp;int i,j;Str_Init(&temp);Str_Assign(&temp,S->ch);//清空SStr_Clear(S);//重新為S分配空間S->length = temp.length + T->length;S->ch = (char*)malloc(sizeof(char) * S->length);//分別將temp和T依次賦值給Sfor(i = 0;i < temp.length;i++)S->ch[i] = temp.ch[i];for(j = 0; j < T->length;j++)S->ch[i++] = T->ch[j];//將temp釋放掉free(temp.ch);}//順序串的比較,如果S>T,返回大於0的值,小於,則返回小於0的值int Str_Compare(HString *S,HString *T){int i;for(i = 0; i < S->length && i < T->length;i++)if(S->ch[i] != T->ch[i])return S->ch[i] - T->ch[i];return S->length - T->length;}//求子串並用Sub返回void Str_GetSub(HString *S,int pos,int len,HString *Sub){int i;//判斷位置和長度的合法性if(pos < 1 || pos > S->length || len < 0 || len > S->length - pos + 1){printf("子串的位置或長度不合法!\n");exit(-1);}else{Str_Clear(Sub);if(len){Sub->ch = (char *)malloc(len * sizeof(char));for(i = 0;i < len;i++)Sub->ch[i] = S->ch[pos + i -1];Sub->length = len;}}}//在順序串中找出給定子串給定位置後出現的第一個的位置int Str_GetSubIndex(HString *S,HString *Sub,int pos){int i,j;//先判斷位置的合法性if(pos < 1 || pos > S->length){printf("位置不合法!\n");exit(-1);}if(Str_IsEmpty(S)){printf("順序串為空白!\n");return -1;}if(Str_IsEmpty(Sub)){printf("給定子串為空白,空串為任何串的子串!\n");return 0;}for(i = pos - 1; i < S->length - Sub->length + 1;i++){for(j = 0; j < Sub->length;j++)if(S->ch[i+j] != Sub->ch[j])break;// 如果找到子串,則j= sub->lengthif(j == Sub->length)return i + 1;}//如果找不對,則返回-1;return -1;}//順序串中插入子串void Str_Insert(HString *S,int pos,HString *T){int i;HString temp;if(pos < 1 || pos > S->length){printf("位置不合法!\n");exit(-1);}if(Str_IsEmpty(T)){printf("子串為空白!\n");exit(0);}Str_Init(&temp);temp.length = S->length + T->length;printf("%d\n",temp.length);temp.ch = (char *)malloc(sizeof(char)*temp.length);for(i = 0 ;i < pos ;i++)temp.ch[i] = S->ch[i];for(; i < pos + T->length;i++)temp.ch[i] = T->ch[i - pos];for(;i < temp.length;i++)temp.ch[i] = S->ch[i - T->length];//將串S 清空,並將串temp賦值給SStr_Clear(S);S->ch = temp.ch;S->length = temp.length;}//在順序串刪除子串void Str_DeleteSub(HString *S,int pos,int len){int i;HString temp;//判斷位置和長度的合法性if(pos < 1 || pos > S->length || len < 0 || len > S->length - pos + 1){printf("子串的位置或長度不合法!\n");exit(-1);}if(Str_IsEmpty(S)){printf("順序串為空白!\n");exit(0);}Str_Init(&temp);temp.length = S->length - len;temp.ch = (char *)malloc(sizeof(char)*temp.length);for(i = 0 ;i < pos - 1; i++)temp.ch[i] = S->ch[i];for(;i < temp.length;i++)temp.ch[i] = S->ch[i+len];//將串S清空,並將串temp賦值給SStr_Clear(S);S->ch = temp.ch;S->length = temp.length;}//列印順序串void Str_Print(HString *S){int i = 0;if(Str_IsEmpty(S)){printf("順序串為空白!\n");exit(0);}elseprintf("%s\n",S->ch);}
《資料結構(C語言版)》之“串的模式比對演算法”
# include <string.h>
# include <stdio.h>
# include <stdlib.h>
# define OK 1
# define ERROR 0
typedef int Status;
//串的定長順序儲存結構
# define MAX_STR_LEN 40
typedef char SString[MAX_STR_LEN + 1];//0號單元存放串的長度
Status StrAssign(SString T,char * chars)//產生一個其值等於chars的串T
{
int i;
if (strlen(chars) > MAX_STR_LEN)
{
return ERROR;
}
else
{
T[0] = strlen(chars);
for (i=1; i<=T[0]; ++i)
{
T[i] = * (chars + i - 1);
}
return OK;
}
}
//返回串S的元素的個數
int StrLength(SString S)
{
return S[0];
}
//用Sub返回串S的自第pos個字元起長度為len的子串
Status SubString(SString Sub,SString S,int pos,int len)
{
int i;
if (pos<1 || pos>S[0] || len<0 || len>S[0]-pos+1)
{
return ERROR;
}
for (i=1; i<=len; ++i)
{
Sub[i] = S[pos+i-1];
}
Sub[0] = len;
return OK;
}
//輸出字串T
void StrPrint(SString T)
{
int i;
for (i=1; i<=T[0]; ++i)
{
printf("%c ",T[i]);
}
printf("\n");
}
//求模式串T的next函數值並存入數組next
void get_next(SString T,int next[])
{
int i = 1,j = 0;
next[1] = 0;
while (i < T[0])
{
if (j==0 || T[i]==T[j])
{
++i;
++j;
next[i] = j;
}
else
{
j = next[j];
}
}
}
//求模式串T的next函數修正值並存入數組nextval
void get_nextval(SString T,int nextval[])
{
int i = 1,j = 0;
nextval[1] = 0;
while (i < T[0])
{
if (j==0 || T[i]==T[j])
{
++i;
++j;
if (T[i] != T[j])
{
nextval[i] = j;
}
else
{
nextval[i] = nextval[j];
}
}
else
......餘下全文>>
資料結構(使用C語言)實現兩個串的比較
不是有int strcmp(char *str1,char *str2);標頭檔string.h這個函數嗎?幹嘛要那麼麻煩。
那就使用這一句吧。除非禁用strcmp();這個函數
int Compare(char *S,char *T)
{
return strcmp(S,T);
}