1.字串與子串、子串行
字串是由零個或多個字元組成的有限序列,子串的定義是串中任意個連續的字元組成的子串行,並規定空串是任意串的子串,任意串是其自身的子串,
2.c風格字串
c++ 語言通常通過
char*/const char*
型別的指標來
c語言中的風格字串。一般來說,我們使用指標的算數操作符來遍歷
c風格字串,每次對指標進行測試並遞增
1,直到到達字串
null
為止。
3.標準庫提供的字串處理函式
c++提供了眾多的字串處理函式,主要如下:
1)strlen
strlen計算字元陣列的字元數,以』\0』為結束標誌,計算不為』\0』的元素的個數。
自定義函式實現strlen
的功能是:
int strlen(const char * str)
assert(strlen != null);
int len = 0;
while((*str++) != 『\0』))
len++;
return len;
2)strcmp
即兩個字串自左向右逐個字元比較(按ascall
值的大小比較),直到出現不同的字元或遇』\0』為止。若s1與s2
相等,返回0;若
s1大於
s2,返回正數,若
s1小於
s2,則返回負數。
自定義實現strcmp
函式的功能:
int strcmp(const char * str1,
const char * str2)
assert(str1 != null && str2 != null);
while(!(ret =*(unsigned char* )str1 - *(unsigned char*)str2 ) && *str1)
str1++;
str2++;
if(ret<0)
ret = -1;
else if(ret > 0)
rer = 1;
return ret;
3)strcat與
strcpy
strcat(dest, src)把所指字串新增到
dest
結尾處(
覆蓋dest
結尾處的』\0』)並新增』\0』;
strcpy(dest, src)把從
src開始且含有
null
結束符的字串複製到以
dest
開始的位址空間。
傳遞給標準庫函式strcat
和strcpy
的第乙個引數陣列必須具有足夠大的空間存放新生的字串。
自定義函式實現strcat
函式的功能:
char * strcat(char * strdest, const char * strsrc )
char * address = strdest;
assert((strdest != null)&&(strcat != null));
while(*srcdest)
srcdest++;
while(*strdest++ = *strsrc++)
return address;
自定義函式實現strcpy()
函式的功能:
char* strcpy(char * strdestination, const char * strsource)
assert((strdestination != null) && (strsource != null));
char *strd = strdestination;
while((*strdestination++ = *strsource++) != 『\0』) ;
return strd;
4)memcpy 與
memset
memcpy函式
void * memcpy(void * dest, const void *src, size_t n);
功能:從源src
所指的記憶體位址的起始位置開始拷貝
n個位元組到目標
dest
所指的記憶體位址的起始位置中,函式返回指向
dest
的指標。
strcpy與
memcpy
的比較
1)複製的內容不同,前者只能複製字串,後者可以複製任意內容。
2)複製方法不同,前者不用指定長度,遇到被複製的字串結束符』\0』時才結束,容易溢位,後者則是根據其第三個引數決定複製的長度。
3)用途不同,通常複製字串時用
strcpy,
而複製其它型別字元時用
memcpy;
memset函式
void* memset(void *s , int ch, size_t n);
功能:作用是將s中前n
個位元組用
ch替換並返回
s,作用是在一塊記憶體中填充某個給定的值,他是對較大的結構體或陣列進行清零操作的一種最快方法。
4.字串的實際應用
1)字串包含問題
可以用兩種方法解決,第一種是串的模式匹配演算法,第二種是kmp演算法
如:給定乙個字串a
,要求在
a中查詢乙個子串b。
深入串的模式匹配演算法(
普通演算法和
kmp演算法
)的詳解
串的定位操作通常稱作串的模式匹配,是各種處理系統中的最重要操作之一。
模式匹配最樸素的演算法是回溯法,即模式串跟主串乙個字元乙個字元的匹配,當模式串中跟主串不匹配時,主串回溯到與模式串匹配開始的下乙個位置,模式串回溯到第乙個位置,繼續匹配。演算法的時間複雜度為o
(m*n
),演算法如下:
//樸素的串的模式匹配演算法,
s為主串,
t為模式串,即找
s中有沒有與
t相同的字串
int index(char *s, char *t, int pos)//pos記錄從哪一位開始匹配可以直接用0代替
//如果相同,則繼續向後比較
else
//如果不同,就回溯,重新查詢
}if (j == strlen(t))
return i-strlen(t); //若匹配成功,返回s中與
t字串相同開始位置的索引
else return 0; //若匹配不成功,返回0}
o(m*n)的時間複雜度有點大,於是人們發現了kmp演算法,核心思想是:當不匹配發生時,主串不回溯,模式串回溯到「合適」的位置,哪個位置合適,只與模式串有關,所以可以先算出模式串中各個字元,當不匹配發生是,應該回溯到哪個位置。演算法整體時間複雜度o(m+m)。
void getnext(char* t, int *next)
else j = next[j];}}
int kmp(char* s, char* t, int pos)
else
j = next[j];
}if (j > strlen(t))
return i-t[0];
else
return 0;
} 求next的操作不是最優的,因為他沒有考慮aaaaaaaaaaaaaaaaaaab的情況,這樣前面會出現大量的1,這樣的演算法複雜度已經和最初的樸素演算法沒有區別了。所以稍微改動一下:
void getnextex(char *t, int *next)
else j = next[j];
} }
2)字串移位包含問題 (略)
第二章 字元和字串處理
一 tchar c text a tchar szbuffer 100 text a string 無論使用ansi還是unicode字元,編譯器都能通過編譯。二 在使用winexec和openfile呼叫的地方,應該用createprocess和createfile呼叫來代替。三 應當遵循的基本準...
第二章簡單動態字串
1.sds的定義 在redis中的字串並不是使用c語言中的char陣列儲存,而是自定義了乙個結構體sds來儲存。redis set msg hello world ok integer 3 在上述例子中,不管是key還是val都是使用sds型別儲存。free屬性的值為0,表示這個sds沒有分配任何未...
第二章 簡單動態字串
在redis中,預設字串的表示型別是sds 簡單動態字串 c語言傳統的字串表示只在很少的情況下用到。sds結構 char buf 用於儲存字串,會在字串結尾自動新增乙個空字元,遵循c字串結尾的慣例,即用n 1字串陣列表示長度為n的字串 unsigned int len buf中已使用的長度,不包含自...