题目

编写高效通用的字符串分割函数 split(const std::string& str, const std::string& delimiter)。将给定文本按任意长度的分隔符(字符或子串)进行彻底切分,返回动态数组 std::vector<std::string>。提供参数选项控制是否丢弃连续分隔符产生的空字符串项(Empty Tokens)。

输入格式:第一行输入原文本;第二行输入用于切分的分隔串。

输出格式:依次输出切分得到的每个子串元素及其编号。

数据范围与约定:字符串长度 <code>≤ 10^5</code>。

思路与算法

1. 多字符分隔符处理
不同于单字符 find(','),通用分割器应支持 "::" 或 "--" 等任意长度分隔符。每次查找成功后步进 delimiter.length()。

2. 末尾残留片断提取
循环结束后,必须提取从最后一个分隔符末尾到源字符串结尾的最后一段剩余子串,否则末尾元素将丢失。

3. 空项过滤策略
在解析 URL 或路径时,连续斜杠 "//" 会产生空字符串;通过 keepEmpty 标志位决定是否将其加入结果数组。

完整程序

#include <iostream>
#include <string>
#include <vector>

std::vector<std::string> split(const std::string& str, const std::string& delimiter, bool keepEmpty = true) {
    std::vector<std::string> tokens;
    if (delimiter.empty()) {
        tokens.push_back(str);
        return tokens;
    }

    std::string::size_type start = 0;
    std::string::size_type end = 0;

    while ((end = str.find(delimiter, start)) != std::string::npos) {
        std::string token = str.substr(start, end - start);
        if (keepEmpty || !token.empty()) {
            tokens.push_back(token);
        }
        start = end + delimiter.length();
    }

    // 处理最后一个分段
    std::string tail = str.substr(start);
    if (keepEmpty || !tail.empty()) {
        tokens.push_back(tail);
    }

    return tokens;
}

int main() {
    std::string text, delim;
    if (!std::getline(std::cin, text) || !std::getline(std::cin, delim)) {
        return 0;
    }

    std::vector<std::string> res = split(text, delim, false);
    std::cout << "成功切分出 " << res.size() << " 个有效片段:\n";
    for (size_t i = 0; i < res.size(); ++i) {
        std::cout << "[" << i << "] \"" << res[i] << "\"\n";
    }

    return 0;
}

运行示例

示例 1:

输入:

root/usr/local/bin//config/app.conf
/

输出:

成功切分出 6 个有效片段:
[0] "root"
[1] "usr"
[2] "local"
[3] "bin"
[4] "config"
[5] "app.conf"

示例 2:

输入:

apple::orange::banana::pear
::

输出:

成功切分出 4 个有效片段:
[0] "apple"
[1] "orange"
[2] "banana"
[3] "pear"