C語(yǔ)言實(shí)現(xiàn)數(shù)據(jù)結(jié)構(gòu)串(堆分配存儲(chǔ)表示法)實(shí)例詳解
更新時(shí)間:2017年07月07日 17:21:59 投稿:lqh
這篇文章主要介紹了C語(yǔ)言實(shí)現(xiàn)數(shù)據(jù)結(jié)構(gòu)串(堆分配存儲(chǔ)表示法)實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下
堆分配存儲(chǔ)表示法
存儲(chǔ)結(jié)構(gòu):
構(gòu)建堆來(lái)存儲(chǔ)字符串,本質(zhì)上是順序表
實(shí)現(xiàn)代碼:
#include <stdio.h> #include <stdlib.h> #include <string.h> #define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0 #define OVERFLOW -2 #define STR_INIT_SIZE 100 #define STRINCREMENT 10 typedef int Status; typedef struct { char *ch; //空串時(shí)指向NULL,非空串時(shí)按串長(zhǎng)分配存儲(chǔ)區(qū) int length; } HString; Status InitString(HString *T) //初始化字符串 { //指針指向NULL,長(zhǎng)度為0即可 //p.s.申請(qǐng)內(nèi)存空間的過(guò)程在賦值中完成 T->ch = NULL; T->length = 0; return OK; } Status StrAssign(HString *T, char *p) //字符串賦值 { //1.判斷T是否已有內(nèi)容,有則釋放 //2.判斷賦值的內(nèi)容是否為空,為空則不賦值 //3.根據(jù)長(zhǎng)度向內(nèi)存申請(qǐng)空間,遍歷賦值給T,長(zhǎng)度等于字符串長(zhǎng)度 //p.s.在這里賦值不賦\0,在打印時(shí)通過(guò)長(zhǎng)度來(lái)判斷字符串結(jié)尾 int i, len = strlen(p); if (T->ch) free(T->ch); if (!len) { T->ch = NULL; T->length = 0; return ERROR; } else { T->ch = (char *)malloc(len * sizeof(char)); if(!T->ch) exit(OVERFLOW); for (i = 0; i < len; ++i) T->ch[i] = p[i]; T->length = len; return OK; } } Status StrPrint(HString T) //打印字符串 { //通過(guò)長(zhǎng)度判斷打印的字符數(shù) int i; for (i = 0; i < T.length; ++i) printf("%c", T.ch[i]); printf("\n"); } Status StrLength(HString T) //字符串長(zhǎng)度 { return T.length; } Status StrEmpty(HString T) //字符串判空 { if (T.length == 0) return TRUE; else return FALSE; } Status Concat(HString *T, HString S1, HString S2) //字符串聯(lián)接 { //1.申請(qǐng)長(zhǎng)度為S1和S2之和的字符串空間 //2.先將S1的元素逐個(gè)賦值到T中 //3.再將S2的元素逐個(gè)賦值到T中 int i; if (T->ch) free(T->ch); T->ch = (char *)malloc((S1.length + S2.length) * sizeof(char)); if (!T->ch) exit(OVERFLOW); for (i = 0; i < S1.length; ++i) T->ch[i] = S1.ch[i]; for (i = 0; i < S2.length; ++i) T->ch[i + S1.length] = S2.ch[i]; T->length = S1.length + S2.length; return OK; } Status StrDelete(HString *T, int pos, int len) //刪除字符串中某個(gè)位置固定長(zhǎng)度的子串 { //pos是字符串中的位置,刪除包括pos的len長(zhǎng)度 int i; if (pos >= T->length) return ERROR; else if(pos + len > T->length) len = T->length - pos + 1; for (i = pos - 1; i < T->length - len; ++i) T->ch[i] = T->ch[i + len]; T->length -= len; T->ch = (char *)realloc(T->ch, T->length * sizeof(char)); if (!T->ch) exit(OVERFLOW); return OK; } Status StrInsert(HString *S, int pos, HString T) { //pos是字符串中的位置,插入時(shí)原來(lái)的元素(包括pos位)后移 int i, len; --pos; len = StrLength(T); S->ch = (char *)realloc(S->ch, (S->length + len) * sizeof(char)); if (pos > S->length) pos = S->length; for (i = S->length - 1; i > pos - 1; --i) S->ch[i + len] = S->ch[i]; for (i = 0; i < len; ++i) S->ch[i + pos] = T.ch[i]; S->length += len; if (!S->ch) exit(OVERFLOW); return OK; } Status Index(HString S, HString T, int pos) //在字符串S中索引位置pos之后的子串t { //同定長(zhǎng)順序存儲(chǔ)表示法 //p.s.傳入的pos是字符串的位置,從1開(kāi)始 //p.s.初始狀態(tài)下T為非空串 if (StrEmpty(T)) return ERROR; int i = pos - 1, j = 0; while(i < S.length && j < T.length) { if (S.ch[i] == T.ch[j]) { ++i; ++j; } else { i = i - j + 1; j = 0; } } if (j >= T.length) return i - j + 1; else return 0; } Status Replace(HString *T, HString S1, HString S2) //將字符串T中等于S1的子串替換成為S2 { //循環(huán)索引子串S1在字符串T中的位置(每次的位置從上一次位置后開(kāi)始查找) //從查找到的位置-1開(kāi)始替換 //p.s.初始狀態(tài)下S1為非空串 int pos = 0; if (StrEmpty(S1)) return ERROR; //當(dāng)pos存在時(shí)循環(huán),當(dāng)全部索引完畢后pos為0 //將索引到的該位置對(duì)應(yīng)的子串刪除后再插入新的子串 do { pos = Index(*T, S1, pos); if (pos) { StrDelete(T, pos, StrLength(S1)); StrInsert(T, pos, S2); } } while(pos); return OK; } Status SubString(HString *Sub, HString S, int pos, int len) { int i; if (pos < 1 || len > S.length || len < 0 || len > S.length - pos + 1) exit(OVERFLOW); if (Sub->ch) free(Sub->ch); //如果查詢的長(zhǎng)度為0,則子串置空 if (len == 0) { Sub->ch = NULL; Sub->length = 0; } else { Sub->ch = (char *)malloc(len * sizeof(char)); for (i = 0; i < len; ++i) Sub->ch[i] = S.ch[pos + i - 1]; Sub->length = len; } return OK; } int main() { int pos; HString t, s, r; char *p = "Hello,String!", *q = "Bye,Bye!"; printf("String *p: %s\n", p); InitString(&t); StrAssign(&t, p); printf("StrAssign... OK.\nString t : "); StrPrint(t); printf("------------------------------\n"); printf("StrLength... OK.\nString Length : %d\n", StrLength(t)); printf("StrEmpty... OK.\n"); if (StrEmpty(t)) printf("String is Empty.\n"); else printf("String is not Empty.\n"); printf("------------------------------\n"); InitString(&s); StrAssign(&s, q); printf("String s : "); StrPrint(s); printf("------------------------------\n"); InitString(&r); Concat(&r, t, s); printf("Concat... OK.\n"); printf("String r : "); StrPrint(r); printf("------------------------------\n"); printf("StrDelete... OK.\n"); StrDelete(&r, 14, 4); printf("String r : "); StrPrint(r); printf("------------------------------\n"); printf("StrInsert... OK.\n"); StrAssign(&t, "Bye,Bye,Bye!"); StrInsert(&r, 14, t); printf("String r : "); StrPrint(r); printf("------------------------------\n"); StrAssign(&t, "ye"); printf("Index... "); StrPrint(t); pos = 1; while(pos) { pos = Index(r, t, pos + 1); if (!pos) break; printf("Position : %d\n", pos); } printf("------------------------------\n"); StrAssign(&t, "ye"); StrAssign(&s, "oo"); Replace(&r, t, s); printf("Replace ye -> ooo ... OK.\n"); printf("String r : "); StrPrint(r); printf("------------------------------\n"); SubString(&t, r, 7, 4); printf("SubString... OK.\n"); printf("String SubString : "); StrPrint(t); printf("------------------------------\n"); return OK; }
感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
相關(guān)文章
C語(yǔ)言動(dòng)態(tài)內(nèi)存管理介紹
大家好,本篇文章主要講的是C語(yǔ)言動(dòng)態(tài)內(nèi)存管理介紹,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽2021-12-12C++之關(guān)于string對(duì)象的大小比較
這篇文章主要介紹了C++之關(guān)于string對(duì)象的大小比較方式,具有很好的 參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-11-11C語(yǔ)言的isatty函數(shù)和ttyname函數(shù)以及sendmsg函數(shù)用法
這篇文章主要介紹了C語(yǔ)言的isatty函數(shù)和ttyname函數(shù)以及sendmsg函數(shù)用法,是C語(yǔ)言入門(mén)學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2015-09-09CreateThread()與beginthread()的區(qū)別詳細(xì)解析
很多開(kāi)發(fā)者不清楚這兩者之間的關(guān)系,他們隨意選一個(gè)函數(shù)來(lái)用,發(fā)現(xiàn)也沒(méi)有什么大問(wèn)題,于是就忙于解決更為緊迫的任務(wù)去了。等到有一天忽然發(fā)現(xiàn)一個(gè)程序運(yùn)行時(shí)間很長(zhǎng)的時(shí)候會(huì)有細(xì)微的內(nèi)存泄露,開(kāi)發(fā)者絕對(duì)不會(huì)想到是因?yàn)檫@兩套函數(shù)用混的結(jié)果2013-09-09C++11新特性之隨機(jī)數(shù)庫(kù)(Random?Number?Library)詳解
相對(duì)于C++11之前的隨機(jī)數(shù)生成器來(lái)說(shuō),C++11的隨機(jī)數(shù)生成器是復(fù)雜了很多,下面這篇文章主要給大家介紹了關(guān)于C++11新特性之隨機(jī)數(shù)庫(kù)(Random?Number?Library)的相關(guān)資料,需要的朋友可以參考下2022-06-06