相較于數(shù)組方式的實現(xiàn),C語言我采用了單鏈表的方式實現(xiàn),C++采用了雙鏈表的方式。毫無疑問,雙鏈表的效率肯定是要遠高于單鏈表的。這次支持中文字符的操作,這個實現(xiàn)的思路是,在節(jié)點類中添加兩個成員變量,一個用來存放char字符,一個用來存放wchar_t字符。關(guān)于兩者的相互轉(zhuǎn)換及輸出請參考 C語言寬字符輸出和轉(zhuǎn)換。
C代碼實現(xiàn)下載 C++代碼實現(xiàn)下載 (備用下載地址 )
這里講一下字符串單鏈表實現(xiàn)的思路和雙鏈表實現(xiàn)的思路(如果不太懂單鏈表的實現(xiàn)和雙鏈表的實現(xiàn)請參考線性表之單鏈表和線性表之雙向鏈表)
毫無疑問,用鏈表的方式來存儲的時候,是一個個節(jié)點進行存儲的,所以一個節(jié)點內(nèi)你可以存放char字符或者wchar_t字符,不想數(shù)組那樣,存放以及取出wchar_t字符是如此的困難。
單鏈表方式: 1.創(chuàng)建一個節(jié)點結(jié)構(gòu)體,里面包含三個字段,分別是char、wchar_t、和Node*。
typedef struct _node{ char c; //窄字節(jié) wchar_t w; //寬字節(jié) _node* next;}Node,*PNode;2.創(chuàng)建一個字符串結(jié)構(gòu)體,用來管理字符節(jié)點,里面包含三個字段,分別是count(字符串長度)、headNode(頭節(jié)點)、endNode(尾節(jié)點)。
typedef struct _string{ int count; //字符個數(shù) PNode headNode; //存放數(shù)據(jù)的節(jié)點(可以理解為一個String有一個頭節(jié)點,然后訪問數(shù)組的時候通過這個頭節(jié)點訪問) PNode endNode; //方便訪問最后一個節(jié)點}String,*PString;3.第三步就是實現(xiàn)字符的增、刪、改、查操作,這個和單鏈表的實現(xiàn)基本相同,就是data域換成了char和wchar_t。
4.第四部就是添加進去后的字符,如何取出作為字符串輸出,那就是將所有節(jié)點的值串起來即可,保存到char*緩沖區(qū)中。
雙鏈表方式: 1.創(chuàng)建一個節(jié)點類,用來存放字符的值,里面包含四個成員變量,分別是c(char字符)、w(wchar_t字符)、next(后繼節(jié)點)、PRe(前驅(qū)節(jié)點)。
2.實現(xiàn)字符的增、刪、改、查,可以參考雙鏈表的實現(xiàn)代碼。
3.取出字符串也是將節(jié)點串起來。所以這一步的操作會比數(shù)組方式慢很多。
總結(jié)一下難點: 第一,如何存儲中文字符,一般判斷該字符的int值是否大于255即可判斷是否是中文字符,大于255就是中文字符,否則是英文字符。之后如果是wchar_t字符就存放在w域中,否則存放在c域中。記住,一個節(jié)點中,c和w一定要有一個為0,否則取出的時候不好判斷。
第二,如何取出中文字符,如果w值不為0,則可以取出,這個步驟還要細分,首先,先把wchar_t字符轉(zhuǎn)換為char[3]數(shù)組,為什么呢?因為一個wchar_t 占2個字符,所以轉(zhuǎn)換后,一個中文字符需要char[0],char[1]兩個字節(jié)來表示。
第三,如何將一個個節(jié)點內(nèi)的字符串成串,創(chuàng)建一個char* buf的緩沖區(qū),然后從頭節(jié)點開始遍歷,如果c不為0,則是英文字符,此時可以取出直接放進buf中,若w不為0,則是中文字符,此時可以取出進行窄字節(jié)的轉(zhuǎn)換后,再放進buf中,此時放進去的是兩個字節(jié)。以此類推,直到最后一個節(jié)點。
第四,這也是最重要的,如果沒有這一步,那么wchar_t的轉(zhuǎn)換以及輸出都會亂碼。那就是用setlocale函數(shù)設(shè)置字符集環(huán)境為中文。具體請參考 C語言寬字符輸出和轉(zhuǎn)換。
新聞熱點
疑難解答