C++ 在C+;中的多个多字符数据表上拆分字符串+;

C++ 在C+;中的多个多字符数据表上拆分字符串+;,c++,string,C++,String,如何在多个多字符分隔符上拆分字符串 我想要一个像vector split\u string(字符串输入,向量delims) 例如,split_字符串(“foo+bar:=baz”、{“+”、“”、“:=”})={“foo”、“+”、“bar”、“”、“:=”、“”、“,”baz”}试试这个 #include <iostream> #include <string> #include <vector> #include <map> std::vec

如何在多个多字符分隔符上拆分字符串

我想要一个像
vector split\u string(字符串输入,向量delims)

例如,
split_字符串(“foo+bar:=baz”、{“+”、“”、“:=”})={“foo”、“+”、“bar”、“”、“:=”、“”、“,”baz”}
试试这个

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

std::vector<std::string> splitString(std::string input, std::vector<std::string> delimeters);
std::string findFirstOf(std::string input, std::vector<std::string> del);

int main()
{
    std::vector<std::string> words = splitString(":=foo+bar :=baz+quaax", { " ",":=","+" });
    for (std::string str : words)
        std::cout << str << ",";
    std::cout << std::endl;
    system("pause");
}
std::vector<std::string> splitString(std::string input, std::vector<std::string> delimeters)
{
    std::vector<std::string> result;
    size_t pos = 0;
    std::string token;
    std::string delimeter = findFirstOf(input, delimeters);

    while(delimeter != "")
    {
        if ((pos = input.find(delimeter)) != std::string::npos)
        {
            token = input.substr(0, pos);
            result.push_back(token);
            result.push_back(delimeter);
            input.erase(0, pos + delimeter.length());
        }
        delimeter = findFirstOf(input, delimeters);
    }
    result.push_back(input);
    return result;
}
//find the first delimeter in the string
std::string findFirstOf(std::string input, std::vector<std::string> del)
{

    //get a map of delimeter and position of delimeter
    size_t pos;
    std::map<std::string, size_t> m;

    for (int i = 0; i < del.size(); i++)
    {
        pos = input.find(del[i]);
        if (pos != std::string::npos)
            m[del[i]] = pos;
    }

    //find the smallest position of all delimeters i.e, find the smallest value in the map

    if (m.size() == 0)
        return "";

    size_t v = m.begin()->second;
    std::string k = m.begin()->first;

    for (auto it = m.begin(); it != m.end(); it++)
    {
        if (it->second < v)
        {
            v = it->second;
            k = it->first;
        }
    }
    return k;
}
#包括
#包括
#包括
#包括
std::vector splitString(std::字符串输入,std::vector delimeters);
std::string findFirstOf(std::string input,std::vector del);
int main()
{
std::vector words=splitString(“:=foo+bar:=baz+quaax”,“{”,“”,“:=”,“+”});
for(std::string str:words)
标准::cout秒秒;
k=它->第一;
}
}
返回k;
}

输出:
,:=,foo,+,bar,,:=,baz,+,quaax,

我的切割同时进行。我选择了分而治之。它不快。这是没有效率的。但这很简单

不幸的是,在这种情况下它不起作用,因为我们在输出中保留了分隔符。分割允许以后的分隔符分割以前找到的分隔符

例如:

恶心

最后,我决定采用与jafar类似的方法,并将其添加到我的支持库中,以便在我正在从事的一项工作中试用,以取代分而治之的方法,因为它看起来确实更快。我不想发帖,但贾法尔的有点太复杂了。没有做过任何分析,所以他的可能会更快

#include <iostream>
#include <vector>

// easy vector output
template<class TYPE>
std::ostream & operator<<(std::ostream & out,
                          const std::vector<TYPE> & in)
{
    for (const TYPE &val: in)
    {
        out << "["<< val << "]";
    }
    return out;
}

// find the first of many string delimiters
size_t multifind(size_t start,
                 const std::string & source,
                 const std::vector<std::string> &delims,
                 size_t & delfound)
{
    size_t lowest = std::string::npos;
    for (size_t i = 0; i < delims.size(); i++)
    {
        size_t pos = source.find(delims[i], start);
        if (pos == start)
        {
            lowest = pos;
            delfound = i;
            break;
        }
        else if (pos < lowest)
        {
            lowest = pos;
            delfound = i;
        }
    }
    return lowest;
}

// do the grunt work
std::vector<std::string> splitString(const std::string &source,
                                     const std::vector<std::string> &delims)
{
    std::vector<std::string> tokens;

    size_t current = 0;
    size_t delfound;
    size_t next = multifind(current,
                            source,
                            delims,
                            delfound);
    while(next != std::string::npos)
    {
        if (current < next)
        {
            tokens.push_back(source.substr(current, next - current));
        }
        tokens.push_back(delims[delfound]);
        current = next + delims[delfound].length();
        next = multifind(current,
                         source,
                         delims,
                         delfound);
    }
    if (current < source.length())
    {
        tokens.push_back(source.substr(current, std::string::npos));
    }
    return tokens;
}


void test(const std::string &source,
          const std::vector<std::string> &delims)
{
    std::cout << "Source " << source << std::endl;
    std::cout << "Delims " << delims << std::endl;
    std::cout << "Result " << splitString(source, delims) << std::endl << std::endl;
}

int main()
{
    test(":=foo+bar  .   :=baz+quaax:=  C++", { " ",":=","+" });
    test(":=foo+bar  .   :=baz+quaax:=  C++", { ":=","+"," " });
    test(":=foo+bar  .   :=baz+quaax:=  C++", { "+"," ",":=" });
    test(":=foo+bar  .   :=baz+quaax:=  C++", { "+"," ",":=",":" });
    test(":=foo+bar  .   :=baz+quaax:=  C++", { ":"," ",":=","+" });
    test("foo+bar  .   :=baz+quaax:=  C++lalala", { "+"," ",":=",":" });
}
#包括
#包括
//简易矢量输出
模板

标准::奥斯特雷姆和运营商非常好的回答,这里还有更多@jafar请链接到适用于多个多字符分隔符的特定答案。@Jonathan Potter请链接到适用于此问题的特定答案第一个链接中的答案解决了这个问题。第一个链接使用单字符分隔符,而第二个链接使用字符串分隔符,精确地说是
=>
。将两者结合起来解决了这个问题。这要求分隔符在字符串中的顺序与分隔符arrayNo中的顺序相同。更改分隔符向量中的顺序,并查看输出是否不同。这个问题是由
findFirstOf
来解决的,但是
splitString(“:=foo+bar:=baz+quaax”,{“+”,“:=”})=:=foo,+,bar:=baz,+,quaax,
不得不说,这比我心目中的N^2分而治之的怪物更优雅。
#include <iostream>
#include <vector>

// easy vector output
template<class TYPE>
std::ostream & operator<<(std::ostream & out,
                          const std::vector<TYPE> & in)
{
    for (const TYPE &val: in)
    {
        out << "["<< val << "]";
    }
    return out;
}

// find the first of many string delimiters
size_t multifind(size_t start,
                 const std::string & source,
                 const std::vector<std::string> &delims,
                 size_t & delfound)
{
    size_t lowest = std::string::npos;
    for (size_t i = 0; i < delims.size(); i++)
    {
        size_t pos = source.find(delims[i], start);
        if (pos == start)
        {
            lowest = pos;
            delfound = i;
            break;
        }
        else if (pos < lowest)
        {
            lowest = pos;
            delfound = i;
        }
    }
    return lowest;
}

// do the grunt work
std::vector<std::string> splitString(const std::string &source,
                                     const std::vector<std::string> &delims)
{
    std::vector<std::string> tokens;

    size_t current = 0;
    size_t delfound;
    size_t next = multifind(current,
                            source,
                            delims,
                            delfound);
    while(next != std::string::npos)
    {
        if (current < next)
        {
            tokens.push_back(source.substr(current, next - current));
        }
        tokens.push_back(delims[delfound]);
        current = next + delims[delfound].length();
        next = multifind(current,
                         source,
                         delims,
                         delfound);
    }
    if (current < source.length())
    {
        tokens.push_back(source.substr(current, std::string::npos));
    }
    return tokens;
}


void test(const std::string &source,
          const std::vector<std::string> &delims)
{
    std::cout << "Source " << source << std::endl;
    std::cout << "Delims " << delims << std::endl;
    std::cout << "Result " << splitString(source, delims) << std::endl << std::endl;
}

int main()
{
    test(":=foo+bar  .   :=baz+quaax:=  C++", { " ",":=","+" });
    test(":=foo+bar  .   :=baz+quaax:=  C++", { ":=","+"," " });
    test(":=foo+bar  .   :=baz+quaax:=  C++", { "+"," ",":=" });
    test(":=foo+bar  .   :=baz+quaax:=  C++", { "+"," ",":=",":" });
    test(":=foo+bar  .   :=baz+quaax:=  C++", { ":"," ",":=","+" });
    test("foo+bar  .   :=baz+quaax:=  C++lalala", { "+"," ",":=",":" });
}