You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++如何实现返回迭代器供调用方构造任意STL容器的字符串分词函数

C++ 分词迭代器实现方案

你需要的是符合STL迭代器规范的惰性分词迭代器,不需要提前把所有分词结果存入中间容器,直接返回迭代器对即可让调用方初始化任意STL容器。

核心实现要点

  • 迭代器必须符合C++标准的输入迭代器类别,这是STL容器构造要求的最低迭代器类别
  • 推荐用string_view存储分词结果,避免不必要的字符串拷贝,大幅提升性能
  • end迭代器用空哨兵实现,不需要提前遍历整个字符串计算总分词数

最简实现示例

以下示例以空格为默认分隔符,你可以自行替换分隔符匹配逻辑:

#include <iterator>
#include <string_view>
#include <cctype>

class SplitIterator {
public:
    // 迭代器特性定义,必须声明才能兼容STL算法和容器
    using iterator_category = std::input_iterator_tag;
    using value_type = std::string_view;
    using difference_type = std::ptrdiff_t;
    using pointer = const value_type*;
    using reference = const value_type&;

    // 构造end哨兵的默认构造函数
    SplitIterator() = default;
    // 构造begin迭代器的构造函数
    explicit SplitIterator(std::string_view input) : input_(input) {
        next(); // 初始化时直接定位第一个分词
    }

    // 解引用运算符重载
    reference operator*() const { return current_; }
    pointer operator->() const { return &current_; }

    // 自增运算符重载
    SplitIterator& operator++() {
        next();
        return *this;
    }
    SplitIterator operator++(int) {
        auto temp = *this;
        next();
        return temp;
    }

    // 迭代器比较逻辑,和哨兵比较时判断是否遍历结束
    bool operator==(const SplitIterator& other) const {
        return input_.empty() && other.input_.empty();
    }
    bool operator!=(const SplitIterator& other) const {
        return !(*this == other);
    }

private:
    std::string_view input_;
    std::string_view current_;

    void next() {
        // 跳过开头的空格分隔符,可自行替换为自定义分隔符逻辑
        while (!input_.empty() && std::isspace(static_cast<unsigned char>(input_.front()))) {
            input_.remove_prefix(1);
        }
        if (input_.empty()) {
            current_ = {};
            return;
        }
        // 查找当前分词的结束位置
        size_t end_pos = 0;
        while (end_pos < input_.size() && !std::isspace(static_cast<unsigned char>(input_[end_pos]))) {
            end_pos++;
        }
        current_ = input_.substr(0, end_pos);
        input_.remove_prefix(end_pos);
    }
};

// 封装成分割函数,返回可直接遍历的范围对象
auto split(std::string_view input) {
    struct Range {
        SplitIterator begin_;
        SplitIterator end_;
        SplitIterator begin() const { return begin_; }
        SplitIterator end() const { return end_; }
    };
    return Range{SplitIterator(input), SplitIterator{}};
}

调用示例

返回的迭代器范围可以直接用来构造任意STL容器,也支持范围for遍历:

#include <vector>
#include <list>
#include <set>
#include <iostream>

int main() {
    std::string test_str = "hello world  test split  iterator";
    // 构造vector
    std::vector<std::string_view> vec(split(test_str).begin(), split(test_str).end());
    // 构造list
    std::list<std::string> lst(split(test_str).begin(), split(test_str).end());
    // 构造set
    std::set<std::string> str_set(split(test_str).begin(), split(test_str).end());
    // 直接范围for遍历
    for (auto word : split(test_str)) {
        std::cout << word << '\n';
    }
    return 0;
}

扩展优化思路

  • 如果需要自定义分隔符,可以给SplitIterator添加模板参数或者构造函数参数,传入自定义的分隔符判断可调用对象
  • 使用C++20及以上版本的场景下,可以直接调用标准库的std::ranges::split_view,不需要自行实现迭代器,原生支持用范围构造STL容器
  • 如果需要适配宽字符或者其他字符类型,可以将迭代器改造为模板类,适配wstring_view等不同字符类型的视图

内容的提问来源于stack exchange,提问作者user1408865

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 11:45:04