记录几个C++ string的split函数实现

内容分享2个月前发布
1 0 0

写leetcode发现C++的string没有split真是。。。你看隔壁python就直接

strs = "cpp is stupid"
stupid = strs.split(" ")

这就结束了!抛出来的还是个list,高了不知道多少个华莱士!
当然,非要说split的话不是还有boostQT是不是,但是他不是STL,力扣不能用。。。。

言归正传,直接扔实现吧。当然下面没一个是我自己写的,全是抄的(

版本1:
普通的string操作

void split(const string &s, vector<string> tokens, const string &delimiters = " ")
{
    string::size_type lastPos = s.find_first_not_of(delimiters, 0);
    string::size_type pos = s.find_first_of(delimiters, lastPos);
    while (string::npos != pos || string::npos != lastPos)
    {
        token.push_back(s.substr(lastPos, pos - lastPos)); //use smplace_back after c++11
        lastPos = s.find_first_not_of(delimiters, pos);
        pos = s.find_first_of(delimiters, lastPos);
    }
}

ps:emplace_backpush_back少一个临时变量的构造。
c++17里还有一个使用string_view的解决办法,根上面这个比少了字符串拷贝。

std::vector<std::string_view> splitSV(std::string_view strv, std::string_view delims = " ")
{
    std::vector<std::string_view> output;
    size_t first = 0;

    while (first < strv.size())
    {
        const auto second = strv.find_first_of(delims, first);

        if (first != second)
            output.emplace_back(strv.substr(first, second-first));

        if (second == std::string_view::npos)
            break;

        first = second + 1;
    }

    return output;
}

版本2:
正则表达式

vector<string> split(string &s,std::regex ws_re = regex("\s+"))
{
    return vector<string>(std::sregex_token_iterator(s.begin(), s.end(), ws_re, -1), std::sregex_token_iterator());
}

参数少了不少,也在一行之内结束了。不过需要构造一个regex对象。

版本3:
使用c++20的range,这明显就是实现了split了吧喂!

auto sv = str 
    | ranges::views::split(   ) 
    | ranges::views::transform([](auto &&i) { 
        return i | ranges::to<string>(); }) 
    | ranges::to<vector>();

解释一下发生了什么,range重载了|操作符,类似于linux中的管道,这里split的结果被塞入transformtransform使用了一个匿名函数将切片转换为string,最后构成一个vector返回;
ps:不过c++20什么时候进入生产环境还是个问题呢。

© 版权声明

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
none
暂无评论...