我有一个Boost ublas矩阵,我想把它的内容打印到一个文本文件中。我有以下实现,并且它是有效的。
#include <iostream>
using namespace std;
#include "boostnumericublasmatrix.hpp"
typedef boost::numeric::ublas::matrix<float> matrix;
#include <algorithm>
#include <iterator>
#include <fstream>
int main()
{
fill(m1.begin2(), m1.begin2() + 400 * 500, 3.3);
ofstream dat("file.txt");
for (auto i = 0; i < 400 ; i++) {
for (auto j = 0; j < 500; j++) {
dat << m1(i, j) << "t"; // Must seperate with Tab
}
dat << endl; // Must write on New line
}
我想在不使用嵌套for循环的情况下编写这段代码。我尝试了如下的ostreambuf_iderator API
copy(m1.begin2(), m1.begin2() + 500 * 400, ostream_iterator<float>(dat, "n")); // Can only new line everything
然而,正如您所看到的,连续的元素都是在新行中编写的,我无法像使用嵌套for循环那样实现排序类型。有没有一种方法可以像我在嵌套中所做的那样使用STL算法?
我喜欢Boost Spirit Karma用于这些小型格式化/生成器任务。
直接方法
如果你不介意每行的尾随标签,这里是
在Coliru上直播
matrix m1(4, 5);
std::fill(m1.data().begin(), m1.data().end(), 1);
using namespace boost::spirit::karma;
std::ofstream("file.txt") << format_delimited(columns(m1.size2()) [auto_], 't', m1.data()) << "n";
打印
1.0 → 1.0 → 1.0 → 1.0 → 1.0 →
1.0 → 1.0 → 1.0 → 1.0 → 1.0 →
1.0 → 1.0 → 1.0 → 1.0 → 1.0 →
1.0 → 1.0 → 1.0 → 1.0 → 1.0 →
使用multi_array
视图
当您使用const_multi_array_ref
适配器作为原始存储的"视图"时,您可以获得更大的灵活性:
在Coliru上直播
std::ofstream("file.txt") << format(auto_ % 't' % eol,
boost::const_multi_array_ref<float, 2>(&*m1.data().begin(), boost::extents[4][5]));
这导致了相同的结果,但没有在每行上都有尾随标签:
1.0 → 1.0 → 1.0 → 1.0 → 1.0
1.0 → 1.0 → 1.0 → 1.0 → 1.0
1.0 → 1.0 → 1.0 → 1.0 → 1.0
1.0 → 1.0 → 1.0 → 1.0 → 1.0
更新使用辅助功能:使其可读性更强,不易出错
template <typename T> boost::const_multi_array_ref<T, 2> make_view(boost::numeric::ublas::matrix<T> const& m) {
return boost::const_multi_array_ref<T,2> (
&*m.data().begin(),
boost::extents[m.size1()][m.size2()]
);
}
所以它变成了
在Coliru上直播
std::cout << format(auto_ % 't' % eol, make_view(m1)) << "n";
在我看来,这是非常优雅的
注意当然,这些假设是行主布局。