字符串,简称串。由n(n≥0)个字符组成的有限序列
根据ASCII码,依次比较每一个字符。


更复杂的块链结构:

设S(目标串/主串)和P(模式串)是两个给定的串,在S中找到等于P的子串的过程称为模式匹配。
比较 S[i]与 P[j]:
缺点:
关键:
运行过程:
next数组计算:
/*计算模式串pCHD的next数组*/
pCHD->next[j = 0] = k = -1;//初始化当前(第0个字符)字符的下标和next值
while (j < pCHD->Length) //循环条件是字符下标没有越界j=0~pp_str->Length-1
{ //从已有的next[j]推算next[j++]
if (k == -1 || pCHD->chs[j] == pCHD->chs[k])
{
//如果当前位置字符比较成功,下一个next自然推进
j++; k++;
pCHD->next[j] = k; //写入推进后的k到next[j]
}
else //如果不相等,停止步进j,将k作为比较失败位置,查看k之前的子列
k = pCHD->next[k];
}
nextval数组计算:
相比较于next的计算,其实变动点只有匹配成功里面,如果下一个字符也成功,也就是有重复,那么直接使用前面的nextval。
/*计算模式串pCHD改进后的nextval数组*/
pCHD->nextval[j = 0] = k = -1;//初始化当前(第0个字符)字符的下标和next值
while (j < pCHD->Length) //循环条件是字符下标没有越界j=0~pp_str->Length-1
{ //从已有的nextval[j]推算nextval[j++]
if (k == -1 || pCHD->chs[j] == pCHD->chs[k])
{
//如果当前位置字符比较成功,下一个next自然推进
j++; k++;
//如果产生重复,使用之前的nextval
if(pCHD->chs[j] == pCHD->chs[k])
pCHD->nextval[j] = pCHD->nextval[k];
else
pCHD->nextval[j] = k;
}
else //如果不相等,停止步进j,将k作为比较失败位置,查看k之前的子列
k = pCHD->nextval[k];
}
KMP算法匹配:
int/*返回匹配位置*/ KMPIndex(StringCHD* ps_str/*主串*/,
PatternStringCHD* pp_str/*模式串(字串)*/,
int pos/*从pos处开始搜索*/,
int mode/*0或1:普通失败函数next[j]或改进失败函数nextval[j]*/){
int i = pos; //目标串的初始对比下标
int j = 0; //模式串的初始对比下标
//检查输入参数的合法性:串非空、位置合适
if (pp_str->Length == 0){
printf("模式串不能为空\n");
return -1;
}
if (pos < 0 || pos >= ps_str->Length){
printf("下标越界错误!0~%d", ps_str->Length - 1);
return -2;
}
while (i<ps_str->Length && j<pp_str->Length){
if (j == -1 || ps_str->chs[i] == pp_str->chs[j]){//字符相同,顺利推进
i++; j++;
}
else//比较失败,做模式串的位置回溯,目标串无需回溯
j = (mode == 0 ? pp_str->next[j] : pp_str->nextval[j]);
}
return (j == pp_str->Length) ? i - pp_str->Length
/*达到模式串末尾而退出的循环,匹配成功,返回位置*/
:-3/*未达到模式串末尾而退出的循环,匹配失败*/;
}
设模式串t为”abacabaaad ”,填写其next数组和改进nextval数组。

| j | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
| t | a | b | a | c | a | b | a | a | a | d |
| next[j] | -1 | 0 | 0 | 1 | 0 | 1 | 2 | 3 | 1 | 1 |
| nextval[j] | -1 | 0 | -1 | 1 | -1 | 0 | -1 | 3 | 1 | 1 |
通过栈S将输入整数转换N为8进制表示输出的核心代码如下:
while(N){ Push(S, N%8); N=N/8; }
while(!IsStackEmpty(S)) { Pop(S,e); printf(“%d “,e); }
请编写函数void Convert(int)采用递归的方式完成这种输出,Convert函数输入为待转换的整数。说明设计思想。
void Convert(int N){
if(N){
Convert(N/8);
printf("%d ", N%8);
}
}
已知数组int a[N],设计递归函数:
(1)int find(int* pA, int len, int x)查找x所在的下标并返回,如果无此元素,返回-1.
int find(int* pA, int len, int x)
{
if (pA[--len] == x)return len;
if (len == 0)return -1;
return find(pA, len, x);
}
(2)int get_max(int* pA, int len)求数组的最大值。
int get_max(int* pA, int len)
{
if (len == 0)return pA[0];
int m = get_max(pA, --len);
return m>pA[len] ? m : pA[len];
}
(3)double average(int* pA, int len)求数组的平均值。
double average(int* pA, int len)
{
if (len == 0)return pA[0];
return (average(pA, --len)*len + pA[len]) / (len + 1);
}