Преобразование std :: vector > в std :: vector - PullRequest
0 голосов
/ 01 февраля 2020

Можно ли перебрать двумерный вектор строк и преобразовать строки в двойные? Если это так, что будет лучшим способом сделать это? Я не очень разбираюсь в двухмерных векторах и итераторах, поэтому прошу прощения, если об этом уже спрашивали. Я попытался найти решение, но мне не очень повезло.

Это небольшой пример моего двумерного векторного ввода:

image

Я попытался перебрать свой двумерный вектор в приведенном ниже коде в надежде, что смогу использовать std :: stod () для разбора строк и преобразования их в double, но это не сработало.

// Here is my original vector which I filled by taking input from a csv file
std::vector<std::vector<std::string>> original_matrix;

std::vector<std::vector<double>> doubles_matrix;
doubles_matrix.reserve(original_matrix.size());
for(auto beg = original_matrix.begin(); beg != original_matrix.end(); ++beg)
{
    for(auto ceg = beg->begin(); ceg != beg->end(); ++ceg) {

    }
}

Ответы [ 3 ]

3 голосов
/ 01 февраля 2020

Прежде всего. Есть миллион решений вашей проблемы. Каждый может использовать то, что он хочет. Стили разные. Новичкам, как правило, нравятся решения C -Style более, чем сложные и "современные C ++" решения.

Я мое очень скромное мнение, (только мое личное мнение) ответ пользователя "super" (+1) - намного лучше, чем принятый ответ от пользователя "selb ie". Но OP принял его и, следовательно, это наиболее подходящий ответ для OP.

Я хотел бы показать дополнительное решение, такое же, как и у пользователя "super", только с использованием "более современного" C ++. elements.

У вас есть 2-мерное std::vector. Это очень хороший подход. Теперь вы хотите преобразовать эти std::vector из std::vector из std::string в другой тип данных. Вы даже использовали тег «transform» в своем вопросе.

Для такого преобразования вы можете использовать функцию из библиотеки C ++, которая была сделана именно для этой цели. Он называется std::transform.

Он превращает элементы из контейнера в нечто иное. Он выполняет итерацию по каждому элементу в контейнере, а затем использует «функцию», например, лямбду, для преобразования этого элемента.

Для двухмерных векторов нам необходимо применить std::transform для каждого измерения.

И поскольку такая выделенная функция существует в C ++, я бы порекомендовал использовать ее.

См. Пример ниже:

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

int main() {

    // The source data
    std::vector<std::vector<std::string>> vvs{ {"1","2","3","4"},{"5","6","7","8"},{"9","10","11","12"},{"13","14","15","16"}};

    // Here we will store the result
    std::vector<std::vector<double>> vvd{};

    // Transform 2 dimensional vector
    // Outer vector
    std::transform(vvs.begin(), vvs.end(), std::back_inserter(vvd), [](const std::vector<std::string>&vs) {
        std::vector<double> vd{};
        // Inner vector
        std::transform(vs.begin(), vs.end(), std::back_inserter(vd), [](const std::string& s) { return std::stod(s); });
        return vd;
        });

    // Show debug output
    std::for_each(vvd.begin(), vvd.end(), [](const std::vector<double>& vd) {
        std::copy(vd.begin(), vd.end(), std::ostream_iterator<double>(std::cout, " ")); std::cout << "\n"; });

    return 0;
}

Но, как уже было сказано, каждый может сделать, что он хочет.

2 голосов
/ 01 февраля 2020
#include <vector>
#include <string>

auto convertVector(std::vector<std::vector<std::string>>& stringVec) {
    std::vector<std::vector<double>> output;
    for (auto& vec : stringVec) {
        output.push_back({});
        for (auto& str : vec) {
            output.back().push_back(std::stod(str));
        }
    }

    return output;
}
0 голосов
/ 01 февраля 2020

Преобразование строки в удвоение выполняется с помощью функции strtod :

string s = 3.14;
double d = strtod(s.c_str(), nullptr);

Затем примените вышеупомянутое мое зацикливание векторов любым удобным для вас способом. Вот пример:

void convert(const vector<vector<string>>& stringVectors, vector<vector<double>>& doubleVectors)
{
    doubleVectors.clear();
    doubleVectors.resize(stringVectors.size());

    for (size_t i = 0; i < stringVectors.size(); i++) {
        auto& vs = stringVectors[i];
        auto& vd = doubleVectors[i];
        vd.resize(vs.size());
        for (size_t j = 0; j < vs.size(); j++) {
            vd[j] = strtod(vs[j].c_str(), nullptr);
        }
    }
}
...