一般網(wǎng)站用什么軟件做網(wǎng)站seo優(yōu)化技能
數(shù)據(jù)結(jié)構(gòu)—串
前置說明
由于學(xué)習(xí)Java面向?qū)ο笳Z言走火入魔,試圖在C語言中模擬實現(xiàn)面向?qū)ο笤O(shè)計。里面加入了大量的函數(shù)指針配合結(jié)構(gòu)體來模擬類中的成員方法
故此篇,亦可稱:
面向?qū)ο蟮腃語言程序設(shè)計
用C語言實現(xiàn)串這種數(shù)據(jù)結(jié)構(gòu),并將它應(yīng)用到解決實際問題。
C語言特性的,麻煩的,不如自動回收的要手動管理內(nèi)存,容易出Bug的。(bushi。
編程語言:C語言
IDE:VS Code
函數(shù)實現(xiàn)靈感:出于Java中的String類提供的方法,在C語言實現(xiàn)一下。
串介紹
由于版本更替,計算機對字符處理越來越多,引入了字符串的概念。
串:由零或多個字符組成的有限序列,又稱字符串
一般記為s=“a1a2……an”,s為串的名稱,用雙引號引起來,部分語言由單引號,三引號的寫法。
串的長度串的可見字符數(shù)目個數(shù)就是串的長度,就是上面的a1,a2……,an。
空串空串的長度為0,空串用"“表示。
主串與字串最初的串為主串,在主串中取一部分連續(xù)的字符序列得到一個新串,該串稱為字符串的子串。比如"String"其字串可以是"S”,“Str”,""等。
串的比較兩個串的比較是比較相應(yīng)位置的字符,在ASCII碼集中每個字符都與整數(shù)建立了一一映射。
如比較silly,stupid.第一個字符相等,那么比較第二個字符i,t。我們只需要記得ASCII碼集中小寫字母的編碼是遞增關(guān)系,而26字母表,i在t前面,故認(rèn)為
“i<t”
,比較結(jié)束,我們認(rèn)為silly比stupid小。比較邏輯是這樣的。
若兩個串長度不一,其中一個串比較完了,那么認(rèn)為長串更大。
兩個串相等的充分必要條件:兩個串長度相等且對應(yīng)字符一一相等。
使用說明
1.若在棧上創(chuàng)建String類型 變量,如String s,需要進(jìn)行
String s={.Init=StrInit}
,結(jié)構(gòu)體的局部初始化
如下圖
#include"String.h"
//很可惜不能實現(xiàn)像Java中的this關(guān)鍵字來隱式傳遞參數(shù)。
int main(){//Object-oriented Programming in CString s={.Init=StrInit};s.Init(&s);s.append(&s,"hello");s.toString(&s);printf("\n");s.append(&s,",world!");s.toString(&s);return 0;
}
2.若在棧上創(chuàng)建一個String* 的指針變量,需要調(diào)用newString函數(shù),
String* str=newString();
newString會在堆上創(chuàng)建一個這樣的String變量并返回其地址。
int main(){//Object-oriented Programming in CString* str=newString();str->append(str,"hello, ");char* arr="1,2,3,4,5";str->valueOfCharArrays(str,arr);str->toString(str);return 0;
}
3.由于結(jié)構(gòu)體內(nèi)置freememory函數(shù)指針,通過指針來調(diào)用函數(shù)可以回收自身內(nèi)存,調(diào)用后相當(dāng)于銷毀了自身。若采用指針,請注意將該指針置空。
4.這里麻煩點在于不好好管理內(nèi)存容易泄露。
結(jié)構(gòu)體說明(串的順序結(jié)構(gòu))
以下是動態(tài)字符串定義,全稱Dynamic String,簡稱string。
注意前面字段定義,很顯然這是順序結(jié)構(gòu)的定義。
串的順序結(jié)構(gòu)是用一組地址連續(xù)的存儲單元存儲串中的字符序列,為了擺脫原有字符串的固定性,我們選擇堆區(qū)的內(nèi)存以便我們實現(xiàn)動態(tài)擴容。
我們把\0踢出在外,但注意\0還是存在,只不過由我們內(nèi)部函數(shù)封裝好,始終給\0預(yù)留空間,不對外顯示,使用不受\0限制。
typedef struct string{//順序表!】//字段/屬性/成員char* a;//字符指針int length;//記錄當(dāng)前字符串的長度,也是有效長度。int capacity;//只記錄實際有效的字符容量,不包括'\0','\0'始終額外留一個字節(jié)空間。//--------------------------------------------------------------//成員函數(shù),用函數(shù)指針模擬一下//get函數(shù)int (*getLength)(struct string* self);//獲取當(dāng)前字符串的長度,相當(dāng)于C庫中string函數(shù)。//操作字符串函數(shù)void (*toString)(struct string* self);//打印字符串void (*append)(struct string* self,const char* str);//連接字符串bool (*empty)(struct string* self);//判斷字符串是否為空串。struct string* (*substring)(struct string* self,int startIndex,int endIndex);//原字符串中創(chuàng)建一個對應(yīng)區(qū)間[startIndex,endIndex)的子字符串。//整型,浮點型,字符數(shù)組,單個字符的轉(zhuǎn)化為字符串void (*valueOfInt)(struct string* self,int val);void (*valueOfLong) (struct string* self,long val);void (*valueOfFloat) (struct string* self,float val);void (*valueOfDouble) (struct string* self,double val);void (*valueOfCharArrays)(struct string* self,char val[]);//動態(tài)字符串之間的操作void (*copyOf)(struct string* self,struct string* other);//動態(tài)字符串之間的拷貝。int (*compareTo)(struct string* self,struct string* other);//比較兩個字符串大小bool (*equal)(struct string* self,struct string* other);//比較字符串是否相等。int (*indexOf)(struct string* S,struct string* T,int pos);//BF算法求子串在主串指定pos之后的下標(biāo)。//管理內(nèi)存 void (*Init)(struct string* str); //字符串普通變量構(gòu)造函數(shù)void (*reset)(struct string* self);//重置字符串,如同一開始初始化一樣。效果和newString之后相同。void (*freememory)(struct string* self);//銷毀自身,釋放所有動態(tài)內(nèi)存。使用此方法后記得將原有指針置空處理。
}String;
函數(shù)說明
gitte
測試不夠嚴(yán)謹(jǐn),難免出錯。請自行學(xué)習(xí),并在評論區(qū)指正錯誤,謝讀。