串是由零個或多個字符組成的有限序列,又稱爲字符串。
串中的字符數目稱爲串的長度。
零個字符的串稱爲空串,它的長度爲零。
空格串,是隻包含空格的串。空格串是有內容有長度的,而且可以不止是一個空格。
子串與主串,串中任意個數的連續字符組成的子序列稱爲該串的子串,相應地,包含子串的串稱爲主串。
子串在主串中的位置就是子串的第一個字符在主串中的序號。
串的比較是通過組成串的字符之間的編碼來進行的,而字符的編碼指的是字符在對應字符集中的序號。
串的基本操作和線性表有很大差別,線性表更關注的是單個元素的操作,串中更多的是查找子串位置,得到指定位置子串、替換子串等操作。
一般用定長數組來存儲串的,可以將實際的串長度值保持在數組的0下標位置。
子串的定位操作通常稱爲串的模式匹配,應該算是串中最重要的操作之一。
樸素的模式匹配算法:
int Index(String S, String T, int pos)
{
int i = pos;
int j = 1;
while (i <= S[0] && j <= T[0])
{
if (S[i] == T[j])
{
++i;
++j;
}
else
{
i = i - j + 2;
j = 1;
}
}
if (j > T[0])
return i - T[0];
return 0;
}
KMP算法,可以大大避免重複遍歷的情況:
void get_next(String T, int *next)
{
int i, j;
i = 1;
j = 0;
next[1] = 0;
while (i < T[0])
{
if (j == 0 || T[i] == T[j])
{
++i;
++j;
next[i] = j;
}
else
j = next[j];
}
}
int Index_KMP(String S, String T, int pos)
{
int i = pos;
int j = 1;
int next[255];
get_next(T, next);
while (i <= S[0] && j <= T[0])
{
if (j == 0 || S[i] == T[j])
{
++i;
++j;
}
else
j = next[j];
}
if (j > T[0])
return i - T[0];
return 0;
}
KMP算法改進:
void get_nextval(String T, int *nextval)
{
int i, j;
i = 1;
j = 0;
nextval[1] = 0;
while (i < T[0])
{
if (j == 0 || T[i] == T[j])
{
++i;
++j;
if (T[i] != T[j])
nextval[i] = j;
else
nextval[i] = nextval[j];
}
else
j = nextval[j];
}
}