char str[10] = "china";
char *p = str;
print sizeof(str) = %lu, sizeof(p) = %lu , sizeof(str), sizeof(p);
=> sizeof(str) = 10; //是str的空间大小
=> sizeof(p) = 4; // 内存地址的大小
=> unsight long sizeof(){} 输出使用 %lu
朴素的字符串匹配算法
#include <string.h>
#include <assert.h>
/*
1. const string &t 查找的父串
2. const string &s 被查找的串
*/
int match_str(const string &t, const string &s)
{
int len1 = t.length();
int len2 = s.length();
//异常
if( len1 < len2) return -1; //长度不够
int i=0, j=0;
while(i < len1 && j < len2)
{
if(t[i] == s[j]){
i++;
j++;
}else{ //不匹配时返回0
i = i - j + 1;
j = 0;
}
}
if(j == len2){
return i - j;
}else
return -1;
}
KMP 算法
// 1. 计算字符串特征向量; s: search_string, t: target_string
s[i] != t[j];
=> s[0,i-1] = t[j-i, j-1];
=> k
=> 如果s[0,k-1] = s[i-k,i-1]; 则比较s[k] <> t[j];
=> s[0,k-1]称为最长前缀子串
特征向量伪码:滑动块
i = 0, next[0] = 0;
i > 0; k = next[i-1];
while (i > 0 && s[i] != s[k]) //只要不相等,就向右滑动
k = next[k-1];
if s[i] = s[k]
next[i] = k + 1;
else
next[i] = 0;
实现:
void next(const string &s, int& next[])
{
next[0] = 0;
for(int i =1; i < s.lenght(); i++)
{
k=next[i-1];
while(i > 0 && s[i] != s[k]) k = next[k-1];
if(s[i] = s[k])
next[i] = k + 1;
else
s[i] = 0; //没有前缀
}
}
// 2. KMP算法匹配
int KMP_match(const string &t, const string &s)
{
//异常
if(s.length() < t.length()) return -1;
int j = 0;
int i = 0;
while( i < t.length() && j < s.length())
{
if(t[i] = s[j]){
i++; j++
};
else //不匹配时, 使用next
j = next[j];
}
if(j == s.length())
return i-j;
else
return -1;
}