• 手写一个自己的mystrstr


    一、数组方式来实现 

    1. // 手写一个自己的Mystrstr:很有价值。
    2. #include<stdio.h>
    3. char* mystrstr(char* dest, char* src)
    4. {
    5. char* p = NULL; // 使用了可能未初始化的本地指针变量p
    6. int i = 0;
    7. int j = 0;
    8. while (dest[i] != '\0')
    9. {
    10. while (dest[i] == src[j])
    11. {
    12. i++;
    13. j++; // j从0开始,当++后,刚好为strlen值。终止条件。
    14. if (strlen(src) == j)
    15. {
    16. p = &dest[i - strlen(src)];
    17. return p;
    18. }
    19. }
    20. // 如果三位,有两位相同,找第三位,则需将前面所有推翻。
    21. i = i - j;
    22. j = 0;
    23. i++;
    24. }
    25. return p;
    26. }
    27. // 每个循环都需要回到当前字符,内循环会把字符往后放很多,需要在外循环回归。
    28. int main06()
    29. {
    30. //char* p = strstr("all hello world, bllo allo a", "llo");
    31. //printf("%s\n", p);
    32. //char* p1 = mystrstr(" hello world , llo allo", "llo");
    33. char* p1 = mystrstr(" hell,", "llo");
    34. //char* p1 = mystrstr("all ol hello world, bllo allo a", "llo");
    35. //char* p1 = mystrstr(" all ol hellllo world, bllo allo a ", "llo");
    36. printf("%s\n", p1);
    37. system("pause");
    38. return 0;
    39. }

    二、采用指针的方式实现

    1. # include<stdio.h>
    2. char* mystrstr01(char* dest, char* src)
    3. {
    4. // 不用计数器了,简单明了。
    5. char* p = NULL;
    6. char* tmp = src;
    7. while (*dest) // 或者while(*dest != '\0')
    8. {
    9. p = dest; // 因为返回的是dest中满足条件的起始位置,所以,先把p放在dest上。
    10. while (*dest == *tmp) // 解引用,内容相同。
    11. {
    12. //printf("*tmp = %c, *dest = %c\n", *tmp, *dest);
    13. tmp++;
    14. if (!*tmp) // 或者if(*tmp == '\0')
    15. {
    16. return p; // 此时的p在内循环起始位置。如果满足条件,返回的刚好为起始位置。
    17. }
    18. dest++;
    19. }
    20. // 没有这步,则不对。因为从循环中出来,会直接跳到下一个字符。
    21. // 需要从上次不符合的下一个字符开始。
    22. dest = p; // dest重新回到外循环的起始位置,等待下一步递增。
    23. tmp = src; // 指向src的重新回到起点。// 回拨到起点。
    24. //printf("dest = %c\n", *dest);
    25. printf("%s\n", src); // src没有变化。用tmp变量保护了。
    26. dest++; // dest重新加一,继续比对。
    27. }
    28. return NULL;
    29. }
    30. // 每个循环都需要回到当前字符,内循环会把字符往后放很多,需要在外循环回归。
    31. int main07()
    32. {
    33. char* p = strstr("all hello world, bllo allo a", "llo");
    34. //printf("%s\n", p);
    35. //char* p1 = mystrstr01(" hello world , llo allo", "llo");
    36. //char* p1 = mystrstr01(" hell,", "llo");
    37. //char* p1 = mystrstr01("all ol hello world, bllo allo a", "llo");
    38. char* p1 = mystrstr01(" all ol hellllo world, bllo allo a ", "llo");
    39. printf("%s\n", p1);
    40. system("pause");
    41. return 0;
    42. }

    理清思路很重要。

    从结构上看其实就是两层循环:内循环和外循环。

    • 外循环就是从dest每个char开始,依次建立子string,
    • 然后内循环中与src比对。
      • 如果满足进内循环,并且输出这个char的位置。
      • 不满足移动到下一个char。

    因此,每次内外的切换都需要有两次回拨至起点的操作。

    • 内循环如果不满足,需要重新回到dest的起始位置,然后加1。开启下一波循环。
    • 此时遍历src,也需要回到src的起始位置,等待下一波循环。

    输入的src和dest就是起点。

    输出为dest中子字符串的起点,因此可以将输出p直接置于dest上。

    p = dest;

    此时的p既可以直接作为输出,又可以记录每次外循环开始时的位置。

    所以在回拨dest时,可以反过来,让dest = p.

    dest = p;

    在指针中:temp相当于记录src的起始位置,每次外循环temp都要回到src的起点位置。

    所以每次内循环temp = src

  • 相关阅读:
    Easyui DataGrid combobox联动下拉框内容
    Python 实现获取【昨天】日期
    Linux C 进程间通信
    GitHub 下载量过百万,阿里 P8 秘密分享的「亿级并发系统设计」
    批量更改文件名 - 大师汇总
    [附源码]JAVA毕业设计沙县小吃点餐系统(系统+LW)
    1.K3s+Rainbond之在线安装
    《刺客信条:起源》画面BUG?我先“退”一步!
    51单片机自学报告--实验部分
    2023 Visual Studio Code 插件推荐:18 个提高开发效率的常用插件
  • 原文地址:https://blog.csdn.net/xiaoyaolangwj/article/details/126415606