1.字符串的模式匹配:bf 时间复杂度n(m-n+1)
char *strfind(const char *s1, const char *s2) { assert(s1 && s2); if(strlen(s1) < strlen(s2)) return NULL; int i, j; for( i = 0; i <= strlen(s1) - strlen(s2); i++) { for( j = 0; j < strlen(s2); ++j) { if(s1[i + j] != s2[j]) break; } if(j == strlen(s2)) { return s1+i; } } return NULL; }
2.kmp: 时间复杂度o(m+n)
int kmp_search(char *s1, char *s2) { int next[strlen(s2)]; get_next(s2, next); int i = 0, j = 0; while(i != strlen(s1) && j < (int)strlen(s2))//strlen返回值为size_t,下面j=-1时不能与size_t比较,会导致-1取模 { if(j == -1 || s1[i] == s2[j]) { i++; j++; }else { j = next[j]; } } if(j >= (int)strlen(s2)) return (i-j); else return -1; } void get_next(char *str, int *next) { int i = 0; int j = -1; next[0] = -1; while(i < strlen(str)) { if(j == -1 || str[i] == str[j]) { i++; j++; if(str[i] == str[j]) { next[i] =next[j]; } else { next[i] = j; } }else j = next[j]; } }3.字符串移位包含问题: 1)字符串s1 长度小于s2长度,返回0
2)连接s1,得到新串s1s1 ,然后判定s2是不是s1的子串
4.快速查出串s2中的字母是否在s1中都有:
1).对每个串排序,然后同时轮询 o(mlogm)+o)nlogn) +o(m+n)
2)hashtable 时间复杂度o(m+n)
3) 质数相乘对单个作除法看能否整除
5.去掉字符串多余的空格
void killspace(char *str) { while(str[i] != '\0') { while(str[i] == ' ') i++; while(str[i] != ' ' && str[i] != '\0') str[j++] = str[i++]; if(str[i] != '\0') str[j++] = str[i++];//加入非空字符后的第一个空字符,考虑末尾的特殊情况 } str[j] = '\0'; }
6.一个字符串中找第一个只出现一次的字符,判断所有字符是否都不同,删除重复字符--》使用hashtable时间复杂度为o(n)
7.strcpy和memcpy的不同
8.大数相乘
void multiple(const char *s1, const char *s2) { int n1 = strlen(s1); int n2 = strlen(s2); //int arr[n1+n2] = {0};//可变空间大小必须动态申请 int *arr = calloc(n1+n2, sizeof(int)); int i, j; for(i = 0; i < strlen(s1); i++) for(j = 0; j < strlen(s2); j++) { arr[i+j+1] += (s1[i] - '0')*(s2[j] - '0');//从下标为1开始,可能向前进位 } //进位 for(i = n1+n2-1; i >= 0; --i ) if(arr[i] >= 10) { arr[i-1] += arr[i]/10; arr[i] %= 10; } // char str[n1+n2+1] = {0}; char *str = calloc(n1+n2, sizeof(char)); i = 0; while(arr[i] == 0) i++; for(j = 0; i < n1+n2 ; i++ ,j++) { str[j] = arr[i] + '0'; } str[j] = '\0'; printf("%s\n", str); }
9.标准strcpy的写法:断言,不能改变目的指针, 返回指针,
10字符串中所有空格替换为'%20': 1.遍历字符串,统计空格数,根据空格数开辟一个新区间,用于存储替换后的字符串
2.从字符串末尾开始遍历,每遇到一个空格,以'%20'代替,否则将字符存在新开辟的区间-->两个字符串中的快慢指针的思想