C语言判断字符串旋转关系与子串包含问题

发布时间:2024年01月12日

?

目录

?引言:

代码:

方法一:通过循环实现字符串的左移操作,并检查是否为另一个字符串旋转而来

方法二:使用strncat和strstr函数判断一个字符串是否为另一个字符串的旋转版本

解析:

1. left_move 函数:字符串左旋转

逻辑解析:

2. left_move_e 函数:判断字符串是否旋转而来

逻辑解析:

3. matching 函数:子串检测

逻辑解析:

4. 主函数 main:

逻辑解析:

函数解释:

strstr 函数:在字符串中查找子串

strncat 函数:追加指定数量的字符


引言:

????????我们将详细解析两个相关的C语言函数,它们分别用于字符串左旋转和判断一个字符串是否是另一个字符串的旋转结果。同时,我们还会探讨一个字符串匹配的函数,用于检测一个字符串是否包含另一个字符串。以下是对这些函数的详细解析,着重介绍了 strstrstrncat 函数的用法。

代码:

方法一:通过循环实现字符串的左移操作,并检查是否为另一个字符串旋转而来
#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;
}

方法二:使用strncat和strstr函数判断一个字符串是否为另一个字符串的旋转版本
#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;
}

解析:

1. 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 次。
  • 使用断言确保传入的指针不为空。
  • 通过双重循环实现字符串的左旋转,每次将第一个元素保存到临时变量,然后将后面的元素向前移动,最后将保存的元素放置在字符串末尾。

2. 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;
}

逻辑解析:

  • 函数接收两个字符指针 p1p2 作为参数,判断字符串 p1 是否可以通过左旋转得到字符串 p2
  • 循环调用 left_move 函数,每次左旋转一次,然后与目标字符串 p2 比较。
  • 如果有一次匹配成功,返回1;否则返回0。

3. 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;
    }
}

逻辑解析:

  • 函数接收两个字符指针 p1p2 作为参数,用于检测字符串 p1 是否包含字符串 p2
  • 首先比较两个字符串的长度,如果不相等则返回0。
  • 使用 strncat 函数将字符串 p1 的前6个字符追加到自身末尾,为了处理循环旋转的情况。
  • 使用 strstr 函数检查字符串 p1 是否包含子串 p2,如果找不到则返回0;找到则返回1。

4. 主函数 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;
}

逻辑解析:

  • 初始化两个字符数组 arr1arr2,分别为 "abcdef" 和 "cdefab"。
  • 调用 left_move_e 函数判断是否可以通过左旋转得到匹配。
  • 根据结果输出 "true" 或 "false"。

通过以上解析,我们深入理解了每个函数的实现逻辑。现在,让我们专注于 strstrstrncat 函数的用法。

函数解释:

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个字符追加到自身末尾,以处理循环旋转的情况。

我们希望读者能更清晰地理解这些函数的用法和逻辑!!!

文章来源:https://blog.csdn.net/2302_78381559/article/details/135536567
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。