【練習】塊鏈串的實現
為了方便串的操作,當以連結串列儲存串值時,除表頭指標外,還可附設一個尾指標來指示連結串列中的最後一個結點,並給出當前串的長度。這樣的串儲存結構稱為塊鏈結構。
- 串的儲存結構型別
#define ChunkSize 4
#define stuff '#'
/*串的結點型別定義*/
typedef struct Chunk
{
char ch[ChunkSize];
struct Chunk *next;
}Chunk;
/*鏈串的型別定義*/
typedef struct
{
Chunk *head;
Chunk *tail;
int length;
}LinkString;
- 初始化串
void InitString(LinkString *S)
/*初始化字串S*/
{
S->length=0; /*將串的長度置為0*/
S->head=S->tail=NULL; /*將串的頭指標和尾指標置為空*/
}
- 串的賦值
int StrAssign(LinkString *S,char *cstr)
/*生成一個其值等於cstr的串S。成功返回1,否則返回0*/
{
int i,j,k,len;
Chunk *p,*q;
len=strlen(cstr); /*len為鏈串的長度 */
if(!len)
return 0;
S->length=len;
j=len/ChunkSize; /*j為鏈串的結點數 */
if(len%ChunkSize)
j++;
for(i=0;i<j;i++)
{
p=(Chunk*)malloc(sizeof(Chunk)); /*動態生成一個結點*/
if(!p)
return 0;
for(k=0;k<ChunkSize&&*cstr;k++) /*將字串ctrs中的字元賦值給鏈串的資料域*/
*(p->ch+k)=*cstr++;
if(i==0) /*如果是第一個結點*/
S->head=q=p; /*頭指標指向第一個結點*/
else
{
q->next=p;
q=p;
}
if(!*cstr) /*如果是最後一個鏈結點*/
{
S->tail=q; /*將尾指標指向最後一個結點*/
q->next=NULL; /*將尾指標的指標域置為空*/
for(;k<ChunkSize;k++) /*將最後一個結點用'#'填充*/
*(q->ch+k)=stuff;
}
}
return 1;
}
- 串的狀態
int StrEmpty(LinkString S)
/*判斷串是否為空。如果S為空串,則返回1,否則返回0*/
{
if(S.length==0) /*如果串為空,返回1 */
return 1;
else /*如果串非空,返回0 */
return 0;
}
int StrLength(LinkString S)
/*求串的長度 */
{
return S.length;
}
- 串的複製
int StrCopy(LinkString *T,LinkString S)
/*串的複製操作*/
{
char *str;
int flag;
if(!ToChars(S,&str)) /*將串S中的字元拷貝到字串str中*/
return 0;
flag=StrAssign(T,str); /*將字串str的字元賦值到串T中*/
free(str); /*釋放str的空間 */
return flag;
}
- 串的轉換
int ToChars(LinkString S,char **cstr)
/*串的轉換操作。將串S的內容轉換為字串,將串S中的字元拷貝到cstr。成功返回1,否則返回0*/
{
Chunk *p=S.head; /*將p指向串S中的第1個結點*/
int i;
char *q;
*cstr=(char*)malloc((S.length+1)*sizeof(char));
if(!cstr||!S.length)
return 0;
q=*cstr; /*將q指向cstr */
while(p) /*塊鏈沒結束 */
{
for(i=0;i<ChunkSize;i++)
if(p->ch[i]!=stuff) /*如果當前字元不是填充的特殊字元'#',則將S中字元賦值給q*/
*q++=(p->ch[i]);
p=p->next;
}
(*cstr)[S.length]=0; /*在字串的末尾新增結束標誌*/
return 1;
}
- 串的比較
int StrCompare(LinkString S,LinkString T)
/*串的比較操作。若S的值大於T,則返回正值;若S的值等於T,則返回0;若S的值小於T,則返回負值*/
{
char *p,*q;
int flag;
if(!ToChars(S,&p)) /*將串S轉換為字串p*/
return 0;
if(!ToChars(T,&q)) /*將串T轉換為字串q*/
return 0;
for(;*p!='\0'&&*q!='\0';)
if(*p==*q)
{
p++;
q++;
}
else
flag=*p-*q;
free(p); /*釋放p的空間 */
free(q); /*釋放q的空間*/
if(*p=='\0'||*q=='\0')
return S.length-T.length;
else
return flag;
}
- 串的連線
int StrConcat(LinkString *T,LinkString S)
/*串的連結操作。將串S連線在串T的尾部*/
{
int flag1,flag2;
LinkString S1,S2;
InitString(&S1);
InitString(&S2);
flag1=StrCopy(&S1,*T); /*將串T的內容拷貝到S1中*/
flag2=StrCopy(&S2,S); /*將串S的內容拷貝到S2中*/
if(flag1==0||flag2==0) /*如果有一個串拷貝不成功,則返回0*/
return 0;
T->head=S1.head; /*修改串T的頭指標*/
S1.tail->next=S2.head; /*將串S1和S2首尾相連*/
T->tail=S2.tail; /*修改串T的尾指標*/
T->length=S.length+T->length; /*修改串T的長度*/
return 1;
}
- 串的插入
int StrInsert(LinkString *S, int pos,LinkString T)
/*串的插入操作。在串S的第pos個位置插入串T*/
{
char *t1,*s1;
int i,j;
int flag;
if(pos<1||pos>S->length+1) /*如果插入位置不合法*/
return 0;
if(!ToChars(*S,&s1)) /*將串S轉換為字串s1*/
return 0;
if(!ToChars(T,&t1)) /*將串T轉換為字串t1*/
return 0;
j=strlen(s1); /*j為字串s1的長度*/
s1=(char*)realloc(s1,(j+strlen(t1)+1)*sizeof(char)); /*為s1重新分配空間*/
for(i=j;i>=pos-1;i--)
s1[i+strlen(t1)]=s1[i]; /*將字串s1中的第pos以後的字元向後移動strlen(t1)個位置*/
for(i=0;i<(int)strlen(t1);i++) /*在字串s1中插入t1*/
s1[pos+i-1]=t1[i];
InitString(S); /*釋放S的原有儲存空間*/
flag=StrAssign(S,s1); /*由s1生成串S*/
free(t1);
free(s1);
return flag;
}
- 串的刪除
int StrDelete(LinkString *S,int pos,int len)
/*串的刪除操作。將串S中的第pos個字元起長度為len的子串刪除*/
{
char *str;
int i;
int flag;
if(pos<1||pos>S->length-len+1||len<0) /*引數不合法*/
return 0;
if(!ToChars(*S,&str)) /*將串S轉換為字串str*/
return 0;
for(i=pos+len-1;i<=(int)strlen(str);i++) /*將字串中第pos個字元起的長度為len的子串刪除*/
str[i-len]=str[i];
InitString(S); /*釋放S的原有儲存空間*/
flag=StrAssign(S,str); /*將字串str轉換為串S*/
free(str);
return flag;
}
- 取子串操作
int SubString(LinkString *Sub, LinkString S,int pos,int len)
/*取子串操作。用Sub返回串S的第pos個字元起長度為len的子串。*/
{
char *t,*str;
int flag;
if(pos<1||pos>S.length||len<0||len>S.length-pos+1) /*引數不合法*/
return 0;
if(!ToChars(S,&str)) /*將串S轉換為字串str*/
return 0;
t=str+pos-1; /*t指向字串str中的pos個字元*/
t[len]='\0'; /* 將Sub結束處置為'\0'*/
flag=StrAssign(Sub,t); /*將字串t轉換為Sub */
free(str);
return flag;
}
- 清空串
void ClearString(LinkString *S)
/*清空串操作。將串的空間釋放*/
{
Chunk *p,*q;
p=S->head;
while(p)
{
q=p->next;
free(p);
p=q;
}
S->head=S->tail=NULL;
S->length=0;
}
- 測試示例
/*包含標頭檔案及鏈串的基本操作實現檔案*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include"LinkString.h"
void StrPrint(LinkString S);
void main()
{
int i,j;
int flag;
LinkString S1,S2,S3,Sub;
char *str1="Welcome to";
char *str2=" Data Structure";
char *str3="Computer Architecture";
printf("串的初始化和賦值操作:\n");
InitString(&S1); /*串S1,S2,S3的初始化*/
InitString(&S2);
InitString(&S3);
InitString(&Sub);
StrAssign(&S1,str1); /*串S1,S2,S3的賦值操作*/
StrAssign(&S2,str2);
StrAssign(&S3,str3);
printf("串S1的值是:");
StrPrint(S1);
printf("串S2的值是:");
StrPrint(S2);
printf("串S3的值是:");
StrPrint(S3);
printf("將串S2連線在串S1的末尾:\n");
StrConcat(&S1,S2); /*將串S2連線在串S1的末尾*/
printf("S1是:");
StrPrint(S1);
printf("將串S1的第12個位置後的14個字元刪除:\n");
StrDelete(&S1,12,14); /*將串S1中的第12個位置後的14個字元刪除*/
printf("S1是:");
StrPrint(S1);
printf("將串S2插入到串S1中的第12個字元後:\n");
StrInsert(&S1,12,S3); /*將串S3插入到串S1的第12個字元後*/
printf("S1是:");
StrPrint(S1);
printf("將串S1中的第12個字元後的8個字元取出並賦值給串Sub:\n");
SubString(&Sub,S1,12,8); /*將串S1中的第12個位置後的8個字元取出賦值給Sub*/
printf("Sub是:");
StrPrint(Sub);
}
void StrPrint(LinkString S)
/*鏈串的輸出*/
{
int i=0,j;
Chunk *h;
h=S.head; /*h指向第一個結點*/
while(i<S.length)
{
for(j=0;j<ChunkSize;j++) /*輸出塊中的每一個字元*/
if(*(h->ch+j)!=stuff)
{
printf("%c",*(h->ch+j));
i++;
}
h=h->next; /*h指向下一個結點*/
}
printf("\n");
}
- 測試結果
相關文章
- 【練習】串的堆分配實現
- 演算法練習:求字串的最長重複子串(Java實現)演算法字串Java
- 【練習】樹的實現
- JavaScript實現區塊鏈JavaScript區塊鏈
- 區塊鏈-NFT 的實現原理區塊鏈
- 雲+區塊鏈 實現區塊鏈技術的普惠應用區塊鏈
- 【區塊鏈技術實現】區塊鏈
- 一文讀懂區塊鏈以及一個區塊鏈的實現區塊鏈
- 200行golang 實現的區塊鏈Golang區塊鏈
- 區塊鏈的原理與golang實現例子區塊鏈Golang
- 串的基本運算實現-加密解密串加密解密
- .Net Core實現區塊鏈初探區塊鏈
- 使用Javascript實現小型區塊鏈JavaScript區塊鏈
- 在 iOS 中實現區塊鏈iOS區塊鏈
- 比特幣和區塊鏈(2):比特幣中區塊鏈的實現比特幣區塊鏈
- 【區塊鏈學習】《區塊鏈學習指南》學習筆記區塊鏈筆記
- qsort的模擬實現和練習
- 【練習】二叉樹的實現二叉樹
- V神:區塊鏈上投票流程的實現區塊鏈
- NodeJS實現簡易區塊鏈NodeJS區塊鏈
- 區塊鏈學習區塊鏈
- 區塊鏈習題複習區塊鏈
- 用java實現一個簡單的區塊鏈Java區塊鏈
- 一個簡單的區塊鏈程式碼實現區塊鏈
- 區塊鏈技術指南學習(二)連結虛擬與現實區塊鏈
- 新加坡的政府區塊鏈實驗可以實現監管理解區塊鏈
- python 實現課堂練習Python
- 使用MVC模式實現區塊鏈開發MVC模式區塊鏈
- [譯] 用 Java 程式碼實現區塊鏈Java區塊鏈
- 區塊鏈安全:實現公鏈雙花攻擊的多種方法區塊鏈
- 比特幣的私鑰【區塊鏈生存訓練】比特幣區塊鏈
- 串的堆分配表示與實現
- 如何學習區塊鏈區塊鏈
- blockstack/stacks-blockchain:Stacks 2.0 區塊鏈的Rust實現Blockchain區塊鏈Rust
- 300行Kotlin程式碼實現的區塊鏈Kotlin區塊鏈
- 基於區塊鏈的智慧鎖設計與實現區塊鏈
- 50行python程式碼實現的小區塊鏈Python區塊鏈
- 如何在NEO區塊鏈上實現資訊加密區塊鏈加密