C语言函数列表
1.获取字符串长度
int my_strlen(const char *src) {
assert(src != NULL);
/*方法1*/
int len = 0;
while(*src++ != '\0') {//函数退出条件是src='\0'但之后还进行了自增运算
len++;
}
return len;
/*方法2*/
// const char *psrc = src;
// while(*psrc++ != '\0') ;
// return psrc - src - 1;
}
2.字符串比较
//字符串s与字符串t 相等 返回0
//字符串s与字符串t 不相等 返回1或-1
int my_strcmp(const char *s,const char *t) {
assert(s != NULL && t != NULL);
while(*s == *t) {
if(*s == '\0')
return 0;
s++;
t++;
}
// return ((*(unsigned char *)s > *(unsigned char *)t) > 0)? 1: -1;
return ((*s - *t) > 0)?1:-1;
}
3.字符串比较(前n个字符)
//限制比较个数,只比较前n个字符
//字符串s与字符串t 相等 返回0
//字符串s与字符串t 不相等 返回1或-1
int my_strncmp(const char *s,const char *t,int n) {
assert(s != NULL && t != NULL);
while(n-- && *s == *t) { //条件用n判断但之后n减少了1
if(n == 0 && *s == *t)
return 0;
s++;
t++;
}
return ((*s - *t) > 0)? 1: -1;
}
4.字符串复制
//将src复制到dst
char *my_strcpy(char *dst,const char *src) {
if(src == dst) return dst;
assert(src != NULL && dst != NULL);
char *pdst = dst;
while(*pdst++ = *src++);
//*pdst = '\0'; //该代码可以忽略
return dst;
}
5.字符串复制(指定复制字符数n)
//将src的n个字符复制到dst
char *my_strncpy(char *dst,const char *src,size_t n) {
assert(src != NULL && dst != NULL);
char *pdst = dst;
while(n-- > 0 && *src != '\0')
*pdst++ = *src++;
*pdst = '\0'; //切记勿忘
return dst;
}
6.字符串拼接
//将src拼接到dst后面
char *my_strcat(char *dst,const char *src) {
assert(src != NULL && dst != NULL);
char *pdst = dst;
while(*pdst) pdst++;
while((*pdst++ = *src++) != '\0');
//*pdst = '\0'; //该行可以忽略
return dst;
}
7.字符串拼接(指定拼接字符数n)
//将src的n个字符拼接到dst后面
char *my_strncat(char *dst,const char *src,size_t n) {
assert(src != NULL && dst != NULL);
char *pdst = dst;
while(*pdst) pdst++ ;
while(n-- && (*pdst++ = *src++)) ;
*pdst = '\0';
return dst;
}
8.字符串拷贝到新位置
/*字符串拷贝到新位置,需要配合free使用*/
char *my_strdup(const char *src) {
if(src == NULL) return NULL;
/*先计算字符串长度*/
size_t len = my_strlen(src);
char *new_addr = malloc(len + 1);
char *res = new_addr;
while((*new_addr++ = *src++) != '\0');
return res;
// 测试
// char *str = my_strdup("hello world!");
// printf("%s\n",str);
// free(str);
}
9.字符数组反转(倒序)
char *my_strrev(char *src) {
assert(src != NULL);
char *s = src;
char *t = src + my_strlen(src) - 1;
while(s < t) {
*s ^= *t;
*t ^= *s;
*s ^= *t;
s++;t--;
}
return src;
// 测试
// char s[] = "hello";
// printf("%s\n",my_strrev(s)); //不能使用字符串,因为字符串是常量,无法修改
}
10.字符串转数字
/**
* 字符串转整数即atoi
* 如果第一个非空格字符存在,从数字或者正负号开始做类型转换,
* 检测到非数字或者结束符时停止转换返回相应整数;否则溢出时就返回0
* 判断字符串是不是数字,类似于strtod
*/
int my_atoi(const char *src) {
const char *p = src;
while(*p && (*p == ' ' || *p == '\t' || *p == '\n') ) p++;
long long res = 0;
bool flag = false;
bool valid = false;
if(*p == '+')
p++;
else if(*p == '-') {
p++;
flag = true;
}
/*检测到非数字字符时停止转换,返回整形数否则返回0*/
for(;*p && (*p >= '0' && *p <= '9');p++) {
int sign = (flag == true)?-1:1;
res = res * 10 + sign * (*p - '0');
if((flag && res < 0x80000000) || (!flag && res > 0x7fffffff)) {
res = 0;
break;
}
}
if(*p == '\0') {
valid = true;
}
return (int)res;
}
11.字符串中查找字符
//查找成功则返回该字符第一次出现的位置
//查找失败则返回NULL
char *my_strchr(const char *src,int ch) {
assert(src != NULL);
const char *psrc = src;
while(*psrc != '\0' && *psrc != ch) {
psrc++;
}
return (*psrc == '\0')? NULL : (char *)psrc;
}
12.字符串中查找字符(后面开始)
//查找一个字符c在另一个字符串str中末次出现的位置
//(也就是从str的右侧开始查找字符c首次出现的位置),并返回这个位置的地址。
//如果未能找到指定字符,那么函数将返回NULL。
char *my_strrchr(const char *src,int ch) {
if(src == NULL) return NULL;
const char *rsrc = src;
while(*rsrc!= '\0') rsrc++;
for(--rsrc; *rsrc != ch;--rsrc) {
if(rsrc == src)
return NULL;
}
return (char *)rsrc;
}
13.字符串中查找字符串
//用于判断字符串str2是否是str1的子串。
//如果是,则该函数返回 str1字符串从 str2第一次出现的位置开始到 str1结尾的字符串;
//否则,返回NULL。
/*BF算法的指针版本*/
char *my_strstr(const char *cs,const char *ct) {
assert(cs != NULL && ct != NULL);
const char *s = cs;
const char *t = ct;
for(; *cs != '\0';cs++) {
for(s = cs,t = ct;*t != '\0' && *s == *t;s++,t++);
if(*t == '\0')
return (char *)cs;
}
return NULL;
}
//用于判断字符串str2是否是str1的子串。
//如果是,则该函数返回 str1字符串从 str2第一次出现的位置开始到 str1结尾的字符串;
//否则,返回NULL。
/*BF算法的数组版本*/
char *my_strstr1(const char *cs,const char *ct) {
assert(cs != NULL && ct != NULL);
int len1 = my_strlen(cs);
int len2 = my_strlen(ct);
for(int i = 0; i <= len1 - len2;i++) {
int j = 0;
while(j < len2 && cs[i + j] == ct[j]) j++;
if(j == len2)
return (char *)(cs + i);
}
return NULL;
}
14.get_next
KMP算法中get_next函数分析
关于KMP算法中next函数的详细解析
void get_next(const char *pat,int *next,int n) {
int j = -1;
next[0] = -1;
for(int i = 1; i < n;i++) {
while(j != -1 && pat[j + 1] != pat[i]) j = next[j]; //回退到匹配尾字符的位置
if(pat[j + 1] == pat[i]) j++;
next[i] = j; //更新当前位置的next值
}
}
15.kmp_strstr
//在字符串src中找出 pat字符串出现的第一个位置 (从0开始)
int kmp_strstr(const char *src,const char *pat) {
int slen = my_strlen(src);
int plen = my_strlen(pat);
int *next = malloc(sizeof(int) * plen);
get_next(pat,next,plen);
int j = -1;
for(int i = 0; i < slen;i++) {
while(j > -1 && pat[j + 1] != src[i]) j = next[j];
if(pat[j + 1] == src[i]) j++;
if(j == plen - 1) { //表明模式串最后一个字符被匹配
free(next);
return i - j;
}
}
free(next);
return -1;
}