c ++在std :: vector中存储逗号分隔的int的最快方法是什么

时间:2011-07-19 04:47:29

标签: c++ vector

我有一个逗号分隔的整数,我想将它们存储在std::vector<int>中。目前我手动完成它。是否有任何内置功能可以完成上述功能?

编辑:

我很着急,忘了详细说明 实际上我有包含CSv的字符串(确切地说是Unicode字符串),例如“1,2,3,4,5” 现在我想将它们存储在std::vector<int>中,所以在上面的例子中,我的向量将有五个元素被推入其中。目前我正在通过手动进行此操作,但它的速度很慢以及该代码存在很多混乱

7 个答案:

答案 0 :(得分:4)

这可能不是最有效的方法,但是这里有一种方法可以使用TR1正则表达式功能(我在这个示例中也使用了C ++ 0x lambda语法,但显然它也可以在没有它的情况下完成):< / p>

#include <iostream>
#include <algorithm>
#include <vector>
#include <regex>
#include <iterator>
#include <cstdlib>

std::vector<int> GetList(const std::wstring &input)
{
    std::vector<int> result;
    std::wsregex_iterator::regex_type rex(L"(\\d+)(,|$)");
    std::wsregex_iterator it(input.begin(), input.end(), rex);

    std::transform(it, std::wsregex_iterator(), std::back_inserter(result),
        [] (const std::wsregex_iterator::value_type &m)
            { return std::wcstol(m[1].str().c_str(), nullptr, 10); });

    return result;
}

答案 1 :(得分:3)

为了简单起见,你可以纯粹在STL中使用它(易于阅读,不需要复杂的库),编码速度快,但执行速度不是最快的(尽管你可以调整一下,就像在矢量中预留空间一样:

std::vector<int> GetValues(std::wstring s, wchar_t delim)
{
    std::vector<int> v;
    std::wstring i;
    std::wstringstream ss(s);
    while(std::getline(ss,i,delim))
    {
        std::wstringstream c(i);
        int x;
        c >> x;
        v.push_back(x);
    }

    return v;
}

(不转发(&&)或atoi以保持代码可移植。)

答案 2 :(得分:2)

遗憾的是,STL不允许您在分隔符上拆分字符串。您可以使用boost来执行此操作:(需要最新的C ++编译器,如MSVC 2010或GCC 4.5)

#include <vector>
#include <string>
#include <algorithm>
#include <iostream>
#include <iterator>

#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>

using namespace std;

int main(int argc, char** argv)
{
    string input = "1,2,3,4";
    vector<string> strs;
    boost::split(strs, input, boost::is_any_of(","));

    vector<int> result;
    transform(
        strs.begin(), strs.end(), back_inserter(result),
        [](const string& s) -> int { return boost::lexical_cast<int>(s); }
    );

    for (auto i = result.begin(); i != result.end(); ++i)
        cout << *i << endl;
}

答案 3 :(得分:2)

快速和脏选项是使用C字符串库strtok()函数和atoi():

void Split(char * string, std::vector<int>& intVec)
{
    char * pNext = strtok(string, ",");
    while (pNext != NULL)
    {
        intVec.push_back(atoi(pNext));
        pNext = strtok(NULL, ",");
    }
}

根据需要插入您自己的输入数据验证。

请参阅:

http://www.cplusplus.com/reference/clibrary/cstring/strtok/
http://www.cplusplus.com/reference/clibrary/cstdlib/atoi/

以及宽字符串版本:
http://msdn.microsoft.com/en-us/library/2c8d19sb%28v=vs.71%29.aspx
http://msdn.microsoft.com/en-us/library/aa273408%28v=vs.60%29.aspx

编辑: 请注意,strtok()会修改原始字符串,因此如果需要,请传递副本。

答案 4 :(得分:1)

试试这个:
它将读取由任何字符(您选择)分隔的任何类型(可以使用&gt;&gt;读取) 注意:读取对象后,对象和分隔符之间应该只有空格。因此对于像ObjectSepReader<std::string, ','>这样的东西,它将读取由','。

分隔的单词列表

这使我们可以很容易地使用我们的标准算法:

#include <vector>
#include <sstream>
#include <iostream>
#include <iterator>
#include <algorithm>

int main()
{
    std::stringstream   data("1,2,3,4,5,6,7,8,9");
    std::vector<int>    vdata;

    // Read the data from a stream
    std::copy(std::istream_iterator<ObjectSepReader<int, ','> >(data),
              std::istream_iterator<ObjectSepReader<int, ','> >(),
              std::back_inserter(vdata)
             );

    // Copy data to output for testing
    std::copy(vdata.begin(), vdata.end(), std::ostream_iterator<int>(std::cout," "));
}

让它发挥作用的秘密课程。

template<typename T,char S>
struct ObjectSepReader
{
    T value;
    operator T const&() const {return value;}
};
template<typename T,char S>
std::istream& operator>>(std::istream& stream, ObjectSepReader<T,S>& data)
{
    char        terminator;
    std::string line;

    std::getline(stream, line, S);
    std::stringstream  linestream(line + ':');

    if (!(linestream >> data.value >> terminator) || (linestream.tellg() != line.size()+1) || (terminator != ':'))
    {   stream.setstate(std::ios::badbit);
    }

    return stream;
}

答案 5 :(得分:0)

就个人而言,我会创建一个结构并让向量包含结构的实例。 像这样:

struct ExampleStruct
{
    int a;
    int b;
    int c;
};
vector<ExampleStruct> structVec;

答案 6 :(得分:0)

这个怎么样?

#include <string>
#include <vector>
#include <functional>
#include <algorithm>
#include <iostream>

struct PickIntFunc
{
    PickIntFunc(std::vector<int>& vecInt): _vecInt(vecInt),_pBegin(0){}

    char operator () (const char& aChar)
    {
        if(aChar == ',' || aChar == 0)
        {
            _vecInt.push_back(atoi(std::string(_pBegin,&aChar).c_str()));
            _pBegin = 0;
        }
        else
        {
            if(_pBegin == 0)
            {
                _pBegin = &aChar;
            }
        }
        return aChar;
    }

    const char* _pBegin;
    std::vector<int>& _vecInt;
};


int _tmain(int argc, _TCHAR* argv[])
{
    std::vector<int> vecInt;

    char intStr[] = "1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20";

    std::for_each(intStr,intStr+sizeof(intStr),PickIntFunc(vecInt));

    // Now test it
    std::for_each(vecInt.begin(),vecInt.end(), [] (int i) { std::cout << i << std::endl;});

    return 0;
}