本次刷题顺序是按照卡尔的代码随想录中给出的顺序
对于c语言,没有string类型,所以,字符串只能使用char* s的形式来表示
下面用到的库函数,主要有strlen(char* s)和isspace(char ch),第一个是求字符串s的长度,第二个是判断字符ch是否为空字符。
提到字符串,不得不提经典的匹配算法KMP,KMP比暴力算法高效,是因为它维护了next数组,next数组中存储的是当前下标以前的字符串中,最大相等前后缀的长度。这有什么用呢?那必然是,当模式串(假设下标为j)与文本串(下标为i)当前字符不匹配时,使用next[j - 1]处与i处的字符进行匹配……这样子,在当前字符不匹配时,文本串的下标不需要回退,模式串的下标进行回退即可
如果还是不太理解,可以参考下边这篇博客
void reverseString(char* s, int sSize) {
int left = 0, right = sSize - 1;
char ch;
while(left < right) {
ch = s[left];
s[left] = s[right];
s[right] = ch;
left++;
right--;
}
}
void restr(char* s, int start, int end) {
int left = start, right = end;
char ch;
while(left < right) {
ch = s[left];
s[left] = s[right];
s[right] = ch;
left++;
right--;
}
}
char* reverseStr(char* s, int k) {
int idx = 0, len = strlen(s), end;
for(idx = 0; idx < len; idx += 2*k) {
if(len > idx + k - 1) restr(s, idx, idx + k - 1);
else restr(s, idx, len - 1);
}
return s;
}
/*反转s[start, end]之间的字符*/
void restr(char* s, int start, int end) {
char ch;
int left = start, right = end;
while(left < right) {
ch = s[left];
s[left] = s[right];
s[right] = ch;
left++;
right--;
}
}
/*移除前后和中间多余的空格*/
void RemovESpace(char* s) {
int left = 0, right = strlen(s) - 1;
int idx = 0;
while(isspace(s[left])) left++;
while(isspace(s[right])) right--;
while(left <= right) {
while(isspace(s[left]) && (left + 1 <= right && isspace(s[left + 1]))) left++;
s[idx++] = s[left++];
}
s[idx] = '\0';
}
char* reverseWords(char* s) {
RemovESpace(s);
int len = strlen(s);
restr(s, 0, len - 1);
int idx = 0, slow = 0;
while(idx <= len) {//此处,因为什么可以等于?是因为,s[len]处,是字符串的结束标志'\0'
if(isspace(s[idx]) || s[idx] == '\0') {
restr(s, slow, idx - 1);
slow = idx + 1;
}
idx++;
}
return s;
}
//获取next数组
void GetNext(char* s, int* next, int len) {
next[0] = 0;
int j = next[0], i;
for(i = 1; i < len; i++) {
/*当j和i指向的字符不相等,并且j还没有回退到0时,j进行回退*/
while(j > 0 && s[j] != s[i]) j = next[j - 1];
if(s[j] == s[i]) j++;//当前i,j指向字符相同,则j自增,j表示i处前缀和后缀最大匹配数
next[i] = j;
}
return;
}
int strStr(char* haystack, char* needle) {
int n_len = strlen(needle), h_len = strlen(haystack);
int* next = malloc(sizeof(int) * n_len);
int n_idx = 0, h_idx = 0, cnt = 0;
GetNext(needle, next, n_len);
while(h_idx < h_len) {
if(haystack[h_idx] == needle[n_idx]) {//当前匹配,则两个指针均移动
h_idx++;
n_idx++;
if(n_idx == n_len) return (h_idx - n_idx);//如果匹配完成,则返回下标
}else {//若当前不匹配,视情况移动needle的指针
if(n_idx > 0) n_idx = next[n_idx - 1];//如果可以回退,则回退
else h_idx++;//如果n_idx已经指向0,无法回退,则只能将h_idx自增,再进行下一轮匹配
}
}
return -1;
}
//获取next数组
void GetNext(char* s, int* next, int len) {
next[0] = 0;
int j = next[0], i;
for(i = 1; i < len; i++) {
/*当j和i指向的字符不相等,并且j还没有回退到0时,j进行回退*/
while(j > 0 && s[j] != s[i]) j = next[j - 1];
if(s[j] == s[i]) j++;//当前i,j指向字符相同,则j自增,j表示i处前缀和后缀最大匹配数
next[i] = j;
}
return;
}
bool repeatedSubstringPattern(char* s) {
int len = strlen(s);
if(len == 0) return false;
int* next = malloc(sizeof(int) * len);
GetNext(s, next, len);
/*当最小重复子串的长度可以被字符串原本长度整除,则说明可以由某个子串重复构建而成*/
if(next[len - 1] != 0 && len % ( len - next[len - 1]) == 0) return true;
else return false;
}
冲冲冲!!!明天开始栈与队列,奥里给
866

被折叠的 条评论
为什么被折叠?



