1 指针编程练习:
1.1 字符串左旋
实现一个函数,可以左旋字符串中的n个字符。
例如:
ABCD左旋一个字符得到BCDA
ABCD左旋两个字符得到CDAB
法一(移首补尾法):
#include<stdio.h> #include<string.h> #include<assert.h> void string_left_rotate(char* str, int n) { assert(str != NULL); int sum = strlen(str); for (int i = 0;i < n;i++)//旋转几个字符就循环几次 { char tmp = *str;//1.把第一个字符存起来 for (int j = 0;j < sum - 1;j++) { *(str + j) = *(str + j + 1);//2.把第一个后面的字符依次往前挪动一位 } *(str + sum - 1) = tmp;//3.把第一个字符放到最后 } } int main() { char arr[20] = "ABCDEF"; printf("%s\n", arr); int n = 0; scanf("%d", &n); string_left_rotate(arr, n); printf("%s\n", arr); return 0; }
法二(三步翻转法):
#include<stdio.h> #include<string.h> #include<assert.h> void reverse(char* left, char* right)//字符串逆置(翻转)函数 { assert(left != NULL); assert(right != NULL); while (left < right) { char tmp = *left; *left = *right; *right = tmp; left++; right--; } } void string_left_rotate(char* str, int n) { int sum = strlen(str); assert(str!=NULL); //如ABCDEF n=2 reverse(str, str+n-1);//1.翻转要左旋的n个字符 BA CDEF reverse(str+n, str + sum - 1);//2.翻转要剩余的个字符 BA FEDC reverse(str, str + sum - 1);//3.整体翻转 CDEF AB } int main() { char arr[20] = "ABCEDF"; printf("%s\n", arr); int n = 0; scanf("%d", &n); string_left_rotate(arr, n); printf("%s\n", arr); return 0; }
1.2 字符串旋转结果
字符串旋转
写一个函数,判断一个字符串是否为另外一个字符串旋转之后的字符串。
例如:给定arr1 = AABCD和arr2 = BCDAA,返回1
给定arr1 = abcd和arr2 = ACBD,返回0.
AABCD左旋一个字符得到ABCDA
AABCD左旋两个字符得到BCDAA
AABCD右旋一个字符得到DAABC
法一(暴力穷举法):
//法一(暴力穷举法): #include<stdio.h> #include<string.h> #include<assert.h> int is_string_rotate(char* str1, char* str2) { //穷举str1所有左旋的结果,然后和str2比较(右旋是左旋的特殊形式) assert(str1 != NULL); assert(str2 != NULL); int sum = strlen(str1); for (int i = 0;i < sum;i++)//旋转str1所有的结果 { char tmp = *str1;//1.把第一个字符存起来 for (int j = 0;j < sum - 1;j++) { *(str1 + j) = *(str1 + j + 1);//2.把第一个后面的字符依次往前挪动一位 } *(str1 + sum - 1) = tmp;//3.把第一个字符放到最后 //旋转一个字符比较一次 if (strcmp(str1, str2) == 0) { return 1; } } return 0;//所有结果比较完,没有就返回0 } int main() { char arr1[20] = "ABCDEF"; char arr2[20] = "CDEFAB"; if (is_string_rotate(arr1, arr2))//是就返回1 { printf("yes\n"); } else { printf("no\n"); } return 0; }
法二:
法二用到很多字符串函数,笔试时可以更好展现自己,而且效率更高了
这些字符串函数的详细介绍都放在下面文章了
//法二: #include<stdio.h> #include<string.h> #include<assert.h> int is_string_rotate(char* str1, char* str2) { assert(str1 != NULL); assert(str2 != NULL); if (strlen(str1) != strlen(str2)) { return 0; //长度不相等返回0 } //1.给str1追加一个str1 //如ABCDEF变成ABCDEFABCDEF 这样新字符串的其中6个就包含了原字符串旋转的所有可能 strncat(str1, str1, strlen(str1)); //字符串追加函数,在第一个参数后面追加第三个参数个第二个参数的字符串 //(strcat不能给自己追加,strncat多最后一个参数) //2.比较str2是不是str1新字符串的子字符串(是的话就是str1原字符串旋转得来) char* ret = strstr(str1, str2); //判断第二个参数是否是第一个参数的子字符串 //是的话返回第一个参数中子字符串的首地址,不是的话返回空指针 //注意到如果长度不一样也是子字符串,不合题意,所以一开始判断长度 return ret != NULL; //是空指针返回0,不是返回1 } int main() { char arr1[20] = "ABCDEF"; char arr2[20] = "CDEFAB"; if (is_string_rotate(arr1, arr2))//是就返回1 { printf("yes\n"); } else { printf("no\n"); } return 0; }
2 字符函数和字符串函数
下面讲的函数的头文件: string.h
重点介绍处理字符和字符串的库函数的使用和注意事项
求字符串长度
strlen
长度不受限制的字符串函数介绍
strcpy
strcat
strcmp
长度受限制的字符串函数介绍
strncpy
strncat
strncmp
字符串查找
strstr
strtok
错误信息报告
strerror
字符串操作:C语言中对字符和字符串的处理很是频繁,但是C语言本身是没有字符串类型的,
字符串通常放在常量字符串 中或者 字符数组 中。
字符串常量 适用于那些对它不做修改的字符串函数.
2.1 strlen三种实现
文档:size_t strlen ( const char * str );
1.字符串以 '\0' 作为结束标志,strlen函数返回的是在字符串中 '\0' 前面出现的字符个数
(不包含 '\0')。
2.参数指向的字符串必须要以 '\0' 结束。
3.注意函数的返回值为size_t,是无符号的( 易错 )
代码演示:
#include <stdio.h> #include <string.h> int main() { int len = strlen("abcdef"); printf("%d\n", len); return 0; }
要注意的地方:
#include<stdio.h> #include<string.h> int main() { const char* str1 = "abcd"; const char* str2 = "abcdef"; if (strlen(str1) - strlen(str2) > 0) { printf("str1>str2\n"); } else { printf("srt1<=str2\n"); } return 0; } //输出str1>str2 因为无符号减无符号还是无符号 大于0 //用自己模拟的strlen就不会出现这种问题
strlen函数的模拟实现:(三种方法)
#include<stdio.h> #include<string.h> #include<assert.h> int my_strlen1(const char* str)//计数器版本 { assert(str != NULL); int count = 0; while (*str != '\0') { count++; str++; } return count; } int my_strlen2(const char* str)//递归版本 { assert(str != NULL); if (*str != '\0') return 1 + my_strlen2(str + 1); else return 0; } //左下右上转圈地看 //my(hello) //my(hello) 1+my(ello) =5 //my(ello) 1+my(llo) =4 //my(llo) 1+my(lo) =3 //my(lo) 1+my(o) =2 //my(o) return 1+my(\0) =1 //my(\0):return 0; int my_strlen3(const char* str)//指针减指针版本 { assert(str != NULL); char* ret = str; while (*ret != '\0') { ret++; } return ret - str; } int main() { char arr[] = "hello"; printf("%d\n", strlen(arr)); printf("%d\n", my_strlen1(arr)); printf("%d\n", my_strlen2(arr)); printf("%d\n", my_strlen3(arr)); return 0; }
2.2 strcpy模拟实现
文档:char* strcpy(char * destination, const char * source );
Copies the C string pointed by source into the array pointed by destination, including the
terminating null character (and stopping at that point).
源字符串必须以 '\0' 结束。
会将源字符串中的 '\0' 拷贝到目标空间。
目标空间必须足够大,以确保能存放源字符串。
目标空间必须可变。
代码演示:
#include <stdio.h> #include <string.h> int main() { char arr1[] = "abcdefghi"; char arr2[] = "123"; printf("拷贝前:%s\n", arr1);//拷贝前:abcdefghi strcpy(arr1, arr2); // 字符串拷贝(目标空间,源字符串) printf("拷贝后:%s\n", arr1);//拷贝后:123 return 0; }
strcpy函数的模拟实现
#include<stdio.h> #include<string.h> #include<assert.h> char* my_strcpy(char* dest, const char* src) { assert(dest != NULL); assert(src != NULL); char* ret = dest;//让ret指向dest的起始地址 while (*dest++ = *src++)//'\0'的ASCII码为0拷贝后跳出循环 { ; } return ret; } int main() { char arr1[50] = "#####################"; char arr2[] = "hello world"; //printf("%s\n", strcpy(arr1, arr2)); printf("%s\n", my_strcpy(arr1, arr2)); return 0; }
2.3 strcat模拟实现
文档:char * strcat ( char * destination, const char * source );
Appends a copy of the source string to the destination string. The terminating null character in destination is overwritten by the first character of source, and a null-character is included at the end of the new string formed by the concatenation of both in destination.
源字符串必须以 '\0' 结束。
目标空间必须有足够的大,能容纳下源字符串的内容。
目标空间必须可修改。
字符串自己给自己追加,要用到strncat,用strcat的话 \0被覆盖了
代码演示:
#include <stdio.h> #include <string.h> int main() { char arr1[30] = "hello"; char arr2[] = "world"; strcat(arr1, arr2); printf("%s\n", arr1);//helloworld return 0; }
C语言进阶⑬(字符串函数)+(指针编程题)strlen+strcpy+strcat+strstr+strtok+strerror(中):https://developer.aliyun.com/article/1513076