将向量拆分为多个数组/向量C ++

时间:2019-01-29 15:38:41

标签: c++ vector split type-conversion

我在将字符串向量拆分为较小的整数vector \ array时遇到问题。我的输入矢量数据如下:

std::vector<std::string> v(2);
v[0] = "0 14 150";
v[1] = "1 2 220";
//...

我知道一个解决方案,可以制作三个数组,并使用sstream将数据转换为整数。但我想避免制作“意大利面条”代码。

谢谢你, 彼得。

3 个答案:

答案 0 :(得分:1)

我前一段时间在stackoverflow上发现了一个split函数。不幸的是,我无法再发布链接。

void split(const std::string & str, std::vector<std::string>& cont, const std::string & delims)
{
    std::size_t current, previous = 0;
    current = str.find_first_of(delims);
    while (current != std::string::npos) 
    {
        cont.push_back(std::move(str.substr(previous, current - previous)));
        previous = current + 1;
        current = str.find_first_of(delims, previous);
    }
    cont.push_back(std::move(str.substr(previous, current - previous)));
}

我将需要在字符串中使用定界符(在您的情况下似乎是退格键),并在字符串向量的每个元素上调用函数:

int main()
{
std::vector<std::string> vec{ "0 14 150","1 2 220" };
std::vector<std::vector<int>> intVec(3,std::vector<int>(vec.size()));
for (int i = 0; i < vec.size(); i++)
{
    std::vector<std::string> singleStr;
    split(vec[i], singleStr, " ");
    for (int j=0; j < singleStr.size();j++)
        intVec[j][i] = (std::stoi(singleStr[j]));
}

system("pause");
}

一个更通用的解决方案可能看起来像这样。您可以将其他类型添加到BasicVariant

#include <string>
#include <vector>

class BasicVariant
{
private:
    std::string str;
public:
    BasicVariant(const std::string& _str) :str(_str) {}
    BasicVariant(int value) :str(std::to_string(value)) {}
    BasicVariant(double value) :str(std::to_string(value)) {}
    inline int toInt()const { return *this; }
    inline double toDouble()const { return *this; }
    inline std::string toString()const { return *this; }
    inline bool toBool()const { return toDouble(); }
    inline operator int()const { return std::stoi(str); }
    inline operator double()const { return std::stof(str); }
    inline operator std::string()const { return str; }
    inline operator bool()const { return toDouble(); }
};


template<typename T>
void split(const std::string& str, std::vector<T>& sink, const std::string& delims)
{
    std::size_t current, previous = 0;
    current = str.find_first_of(delims);
    while (current != std::string::npos)
    {
        sink.push_back(std::move(BasicVariant(str.substr(previous, current - previous))));
        previous = current + 1;
        current = str.find_first_of(delims, previous);
    }
    sink.push_back(std::move(BasicVariant(str.substr(previous, current - previous))));
}




int main()
{
    std::vector<std::string> vec{ "0 14 150","1 2 220" };
    std::vector<std::vector<int>> intVec(3, std::vector<int>(vec.size()));
    for (int i = 0; i < vec.size(); i++)
    {
        std::vector<int> row;
        split(vec[i], row, " ");
        for (int j = 0; j < row.size(); j++)
            intVec[j][i] = row[j];
    }

    system("pause");
}

答案 1 :(得分:0)

编辑:我删除了详细的移调功能。


我假设您要将std::vector<std::string>转换为2D矩阵std::vector<std::vector<int>>。 例如,对于您的示例,假定期望的结果为arr1 = {0,1,...}arr2 = {14,2,...}arr3 = {150,220,...}

首先

  • 我们可以使用std::istream_iterator从字符串中提取整数。

  • 我们还可以应用范围构造函数来创建与每个字符串相对应的std::vector<int>

因此以下功能对您有效,至少对我来说,它似乎不是意大利面条代码。 首先,此函数从传递的字符串向量{0,14,150,...}中提取两个整数数组{1,2,220,...}v作为矩阵。 由于默认构造的std::istream_iterator是流结束迭代器,因此每个范围构造函数都会读取每个字符串,直到无法读取下一个值为止。 最后,换位的返回:

#include <vector>
#include <string>
#include <sstream>
#include <iterator>

template <typename T>
auto extractNumbers(const std::vector<std::string>& v)
{
    std::vector<std::vector<T>> extracted;
    extracted.reserve(v.size());

    for(auto& s : v)
    {
        std::stringstream ss(s);
        std::istream_iterator<T> begin(ss), end; //defaulted end-of-stream iterator.

        extracted.emplace_back(begin, end);
    }

    // this also validates following access to extracted[0].
    if(extracted.empty()){
        return extracted;
    }

    decltype(extracted) transposed(extracted[0].size());
    for(std::size_t i=0; i<transposed.size(); ++i){
        for(std::size_t j=0; j<extracted.size(); ++j){
            transposed.at(i).push_back(std::move(extracted.at(j).at(i)));
        }
    }

    return transposed;
}

然后您可以从字符串向量中提取整数,如下所示:

DEMO

std::vector<std::string> v(n);
v[0] = "0 14 150";
v[1] = "1 2 220";
...
v[n-1] = "...";

auto matrix = extractNumbers<int>(v);

其中 matrix[0]arr1matrix[1]arr2,依此类推。 我们还可以通过auto arr1 = std::move(matrix[0]);快速获取它们的内部指针。

答案 2 :(得分:0)

我们这里有些误会。
我的程序的输出应具有三个数组/向量。

输出如下:

arr1| arr1| arr3
0   | 14  | 150
1   |  2  | 220
2   |  4  | 130