C/C++每日一练:编写一个查找子串的位置函数

题目要求

编写一个函数,用于在一个字符串中查找一个子串的位置。如果找到子串,则返回子串在主字符串中第一次出现的位置(从0开始计数);如果未找到子串,则返回-1。

做题思路

  1. 遍历主字符串:从主字符串的第一个字符开始,逐个字符进行遍历。
  2. 匹配子串:对于主字符串中的每一个字符,检查从这个字符开始的后缀子串是否与给定的子串匹配。
  3. 返回位置:如果找到匹配的子串,则返回当前起始字符的位置。
  4. 未找到处理:如果遍历完整个主字符串都没有找到匹配的子串,则返回-1。

过程解析

  • 暴力匹配法:这是最简单的方法,通过两层循环实现。外层循环遍历主字符串的每一个字符,内层循环从当前外层循环的字符开始,逐个字符与子串进行比较。
  • 优化:虽然暴力匹配法简单易懂,但在最坏情况下时间复杂度为O(n*m),其中n是主字符串的长度,m是子串的长度。对于更高效的算法,可以考虑KMP(Knuth-Morris-Pratt)算法或Boyer-Moore算法等,但本文主要实现暴力匹配法。

运用到的知识点

  • 字符串操作:C语言中,字符串是以字符数组的形式存储,并以空字符'\0'结尾。
  • 循环控制:使用for循环或while循环进行字符串遍历。
  • 条件判断:使用if语句进行子串匹配的判断。

示例代码

C 实现

cpp 复制代码
#include <stdio.h>  // 引入标准输入输出库,用于printf函数
#include <string.h>  // 引入字符串处理库,用于strlen函数

// 定义一个函数,用于查找子串在主字符串中的位置
int findSubstring(const char *str, const char *sub) {  
    int strLen = strlen(str);  // 获取主字符串的长度
    int subLen = strlen(sub);  // 获取子串的长度
  
    // 使用for循环遍历主字符串,确保不会越界到子串长度之外
    for (int i = 0; i <= strLen - subLen; i++) {  
        // 定义一个变量j,用于在内层循环中遍历子串
        int j;  
        // 使用for循环遍历子串,从当前主字符串的位置i开始比较
        for (j = 0; j < subLen; j++) {  
            // 如果当前字符不匹配,则跳出内层循环
            if (str[i + j] != sub[j]) {  
                break; // 一旦发现不匹配,跳出内层循环
            }  
        }  
        // 如果内层循环正常结束(此时子串的每一个字符都已匹配完,即j等于子串长度),说明找到了匹配的子串
        if (j == subLen) {  
            return i; // 返回子串在主字符串中的起始位置
        }  
    }  
  
    // 如果遍历完整个主字符串都没有找到匹配的子串,则返回-1
    return -1;  
}  
  
int main() 
{  
    const char *str = "hello world";  // 定义并初始化主字符串
    const char *sub = "world";  // 定义并初始化要查找的子串
    int position = findSubstring(str, sub);  // 调用findSubstring函数查找子串位置
  
    // 根据返回的位置值,打印相应的信息
    if (position != -1) {  
        printf("The position of substring:'%s' in the main string is: %d\n", sub, position);  // 找到子串,打印位置
    } else {  
        printf("No substring found.\n");  // 未找到子串,打印提示信息
    }  
  
    return 0;  // 程序正常结束
}

C++ 实现

cpp 复制代码
#include <iostream>  // 引入输入输出流库,用于std::cout和std::endl
#include <string>  // 引入字符串库,用于std::string类型

// 定义一个函数,用于查找子串在主字符串中的位置
int findSubstring(const std::string &str, const std::string &sub) {  
    int strLen = str.length();  // 获取主字符串的长度
    int subLen = sub.length();  // 获取子串的长度
  
    // 使用for循环遍历主字符串,确保不会越界到子串长度之外
    for (int i = 0; i <= strLen - subLen; i++) {  
        // 定义一个布尔变量match,用于标记当前位置开始的子串是否与给定子串匹配
        bool match = true;  
        // 使用for循环遍历子串,从当前主字符串的位置i开始比较
        for (int j = 0; j < subLen; j++) {  
            // 如果当前字符不匹配,则将match设置为false,并跳出内层循环
            if (str[i + j] != sub[j]) {  
                match = false;  
                break; // 一旦发现不匹配,跳出内层循环
            }  
        }  
        // 如果内层循环正常结束(即j等于子串长度且match为true),说明找到了匹配的子串
        if (match) {  
            return i; // 返回子串在主字符串中的起始位置
        }  
    }  
  
    // 如果遍历完整个主字符串都没有找到匹配的子串,则返回-1
    return -1;  
}  
  
int main() 
{  
    std::string str = "hello world";  // 定义并初始化主字符串
    std::string sub = "world";  // 定义并初始化要查找的子串
    int position = findSubstring(str, sub);  // 调用findSubstring函数查找子串位置
  
    // 根据返回的位置值,打印相应的信息
    if (position != -1) {  
        // 如果找到了子串,则打印子串和它在主字符串中的位置
        std::cout << "The position of the substring: " << sub << " in the main string is: " << position << std::endl;  
    } else {  
        // 如果未找到子串,则打印提示信息
        std::cout << "No substring found" << sub << "'" << std::endl;  
    }  
  
    return 0;  // 程序正常结束
}
相关推荐
老鼠只爱大米10 小时前
LeetCode经典算法面试题 #114:二叉树展开为链表(递归、迭代、Morris等多种实现方案详细解析)
算法·leetcode·二叉树·原地算法·morris遍历·二叉树展开
今儿敲了吗10 小时前
07| 高精度除法
c++
Ivanqhz11 小时前
现代异构高性能计算(HPC)集群节点架构
开发语言·人工智能·后端·算法·架构·云计算·边缘计算
HyperAI超神经11 小时前
覆盖天体物理/地球科学/流变学/声学等19种场景,Polymathic AI构建1.3B模型实现精确连续介质仿真
人工智能·深度学习·学习·算法·机器学习·ai编程·vllm
执着25911 小时前
力扣hot100 - 144、二叉树的前序遍历
数据结构·算法·leetcode
范纹杉想快点毕业11 小时前
嵌入式系统架构之道:告别“意大利面条”,拥抱状态机与事件驱动
java·开发语言·c++·嵌入式硬件·算法·架构·mfc
陳103011 小时前
C++:map和set的使用
开发语言·c++
苏宸啊11 小时前
list底层实现
c++·list
近津薪荼11 小时前
递归专题(4)——两两交换链表中的节点
数据结构·c++·学习·算法·链表
2501_9403152611 小时前
【无标题】2390:从字符串中移除*
java·开发语言·算法