目录
方法一:通过循环实现字符串的左移操作,并检查是否为另一个字符串旋转而来
方法二:使用strncat和strstr函数判断一个字符串是否为另一个字符串的旋转版本
????????我们将详细解析两个相关的C语言函数,它们分别用于字符串左旋转和判断一个字符串是否是另一个字符串的旋转结果。同时,我们还会探讨一个字符串匹配的函数,用于检测一个字符串是否包含另一个字符串。以下是对这些函数的详细解析,着重介绍了 strstr
和 strncat
函数的用法。
#include <stdio.h>
#include <string.h>
#include <assert.h>
void left_move(char* p, int k) {
assert(p != NULL);
int len = strlen(p);
for (int i = 0; i < k; i++) { // 根据指定次数进行左移操作
char tmp = *p; // 将第一个字符暂存到临时变量tmp中
for (int j = 0; j < len - 1; j++) { // 将后续字符依次前移一位
*(p + j) = *(p + j + 1);
}
*(p + len - 1) = tmp; // 最后将临时变量tmp的值赋给原字符串末尾
}
}
int left_move_e(char* p1, char* p2) {
int len = strlen(p1);
for (int i = 0; i < len; i++) {
left_move(p1, 1); // 每次左移一次
int result = strcmp(p1, p2); // 比较左移后的字符串与目标字符串是否相等
if (result == 0) { // 如果相等,则说明p2是p1旋转得到的
return 1;
}
}
return 0; // 遍历完所有可能的左移情况后仍未找到匹配项,返回false
}
int main() {
char arr1[] = "abcdef";
char arr2[] = "cdefab";
int ret = left_move_e(arr1, arr2);
if (ret == 1) {
printf("true");
} else {
printf("false");
}
return 0;
}
#include <stdio.h>
#include <string.h>
int matching(char* p1, char* p2) {
int len1 = strlen(p1);
int len2 = strlen(p2);
if (len1 != len2) {
return 0; // 若长度不等,直接返回false
}
// 不推荐在此处使用strncat,因为这可能会破坏原始字符串arr1
// strncat(p1, p1, len1);
// 由于strncat存在问题,这里采用另一种方式构造新字符串
char concat[strlen(p1)*2+1];
strcpy(concat, p1);
strcat(concat, p1);
// 使用strstr函数检查concat是否包含p2
if (strstr(concat, p2) != NULL) {
return 1; // 如果找到子串p2,则返回true
} else {
return 0; // 否则返回false
}
}
int main() {
char arr1[20] = "abcdef";
char arr2[] = "cdefab";
int set = matching(arr1, arr2);
if (set == 1) {
printf("true");
} else {
printf("false");
}
return 0;
}
left_move
函数:字符串左旋转void left_move(char* p, int k) {
assert(p != NULL);
int len = strlen(p);
for (int i = 0; i < k; i++) {
int tmp = *p;
for (int j = 0; j < len - 1; j++) {
*(p + j) = *(p + j + 1);
}
*(p + len - 1) = tmp;
}
}
- 函数接收一个字符指针
p
和一个整数k
作为参数,表示将字符串向左旋转k
次。- 使用断言确保传入的指针不为空。
- 通过双重循环实现字符串的左旋转,每次将第一个元素保存到临时变量,然后将后面的元素向前移动,最后将保存的元素放置在字符串末尾。
left_move_e
函数:判断字符串是否旋转而来int left_move_e(char* p1, char* p2) {
int len = strlen(p1);
for (int i = 0; i < len; i++) {
left_move(p1, 1);
int set = strcmp(p1, p2);
if (set == 0) {
return 1;
}
}
return 0;
}
- 函数接收两个字符指针
p1
和p2
作为参数,判断字符串p1
是否可以通过左旋转得到字符串p2
。- 循环调用
left_move
函数,每次左旋转一次,然后与目标字符串p2
比较。- 如果有一次匹配成功,返回1;否则返回0。
matching
函数:子串检测int matching(char* p1, char* p2) {
int len1 = strlen(p1);
int len2 = strlen(p2);
if (len1 != len2) {
return 0;
}
strncat(p1, p1, 6);
if (strstr(p1, p2) == NULL) {
return 0;
}
else {
return 1;
}
}
- 函数接收两个字符指针
p1
和p2
作为参数,用于检测字符串p1
是否包含字符串p2
。- 首先比较两个字符串的长度,如果不相等则返回0。
- 使用
strncat
函数将字符串p1
的前6个字符追加到自身末尾,为了处理循环旋转的情况。- 使用
strstr
函数检查字符串p1
是否包含子串p2
,如果找不到则返回0;找到则返回1。
main
:int main() {
char arr1[] = "abcdef";
char arr2[] = "cdefab";
int ret = left_move_e(arr1, arr2);
if (ret == 1) {
printf("true");
}
else {
printf("false");
}
return 0;
}
- 初始化两个字符数组
arr1
和arr2
,分别为 "abcdef" 和 "cdefab"。- 调用
left_move_e
函数判断是否可以通过左旋转得到匹配。- 根据结果输出 "true" 或 "false"。
通过以上解析,我们深入理解了每个函数的实现逻辑。现在,让我们专注于 strstr
和 strncat
函数的用法。
strstr
函数:在字符串中查找子串char *strstr(const char *haystack, const char *needle);
haystack
是要搜索的字符串,needle
是要查找的子串。- 如果找到子串,返回指向第一次出现子串的位置的指针;否则,返回
NULL
。
在 matching
函数中,我们使用了 strstr
函数来检查字符串 p1
是否包含子串 p2
。
strncat
函数:追加指定数量的字符char *strncat(char *dest, const char *src, size_t n);
dest
是目标字符串,src
是要追加的字符串,n
是要追加的字符数。- 将
src
的前n
个字符追加到dest
的末尾。
在 matching
函数中,我们使用了 strncat
函数将字符串 p1
的前6个字符追加到自身末尾,以处理循环旋转的情况。
我们希望读者能更清晰地理解这些函数的用法和逻辑!!!