将 std::vector<std::vector<std::string>> 转换为 std::vector<std::vector<double>>
Converting std::vector<std::vector<std::string>> to std::vector<std::vector<double>>
是否可以遍历二维字符串向量并将字符串转换为双精度数?如果是这样,这样做的最佳方法是什么?我对二维向量和迭代器相当缺乏经验,所以如果之前有人问过这个问题,我深表歉意。我试图找到解决方案,但运气不佳。
这是我的二维向量输入的一个小样本:
我试图在下面的代码中遍历我的二维向量,希望我可以使用 std::stod() 来解析字符串并将它们转换为双精度数,但它没有用。
// 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) {
}
}
将字符串转换为双精度是使用 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);
}
}
}
#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;
}
首先。您的问题有一百万种解决方案。每个人都可以使用他想要的东西。风格不同。新手通常更喜欢 C 风格的解决方案,而不是复杂的 "modern C++" 解决方案。
我的拙见,(仅个人意见)用户 "super" (+1) 的回答比用户 "selbie" 接受的答案要好得多。但是OP接受了,因此,这是OP最合适的答案。
我想展示一个额外的解决方案,它与用户 "super" 相同,只是使用 "more-modern" C++ 元素。
你有一个二维 std::vector
。这是一个非常好的方法。现在您想将此 std::vector
of std::vector
of std::string
转换为不同的数据类型。您甚至在问题中使用了标签 "transform"。
对于这种转换,您可以使用 C++ 库中专门为此目的而创建的函数。它被称为std::transform
。
它将容器中的元素转换成不同的东西。它遍历容器中的每个元素,然后使用 "function",例如 lambda,来转换该元素。
对于二维向量,我们需要为每个维度应用 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;
}
但是,正如所说,每个人都可以做他想做的事。
是否可以遍历二维字符串向量并将字符串转换为双精度数?如果是这样,这样做的最佳方法是什么?我对二维向量和迭代器相当缺乏经验,所以如果之前有人问过这个问题,我深表歉意。我试图找到解决方案,但运气不佳。
这是我的二维向量输入的一个小样本:
我试图在下面的代码中遍历我的二维向量,希望我可以使用 std::stod() 来解析字符串并将它们转换为双精度数,但它没有用。
// 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) {
}
}
将字符串转换为双精度是使用 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);
}
}
}
#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;
}
首先。您的问题有一百万种解决方案。每个人都可以使用他想要的东西。风格不同。新手通常更喜欢 C 风格的解决方案,而不是复杂的 "modern C++" 解决方案。
我的拙见,(仅个人意见)用户 "super" (+1) 的回答比用户 "selbie" 接受的答案要好得多。但是OP接受了,因此,这是OP最合适的答案。
我想展示一个额外的解决方案,它与用户 "super" 相同,只是使用 "more-modern" C++ 元素。
你有一个二维 std::vector
。这是一个非常好的方法。现在您想将此 std::vector
of std::vector
of std::string
转换为不同的数据类型。您甚至在问题中使用了标签 "transform"。
对于这种转换,您可以使用 C++ 库中专门为此目的而创建的函数。它被称为std::transform
。
它将容器中的元素转换成不同的东西。它遍历容器中的每个元素,然后使用 "function",例如 lambda,来转换该元素。
对于二维向量,我们需要为每个维度应用 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;
}
但是,正如所说,每个人都可以做他想做的事。