此代码预先计算n个大小的tic tac脚趾板的获奖组合。
我首先使用命令式方法创建了我的函数。这正是我大多数时候自然地编写代码的方式。然后我试着用“我想完成什么?”来思考这个问题。方法,而不是“我想要它做什么?”最后,我想我还是采用了一种命令式的方法,只使用STL算法作为循环。
必须采取的办法:
std::vector<std::vector<int>> rules3(const int x){
using namespace std;
vector<vector<int>> seqs;
for(int n=0; n<x; ++n){
vector<int> seq;
for(int m=0; m<x; ++m){
seq.push_back(n*x+m);
}
seqs.push_back(seq);
}
for(int n=0; n<x; ++n){
vector<int> seq;
for(int m=0; m<x; ++m){
seq.push_back(n+x*m);
}
seqs.push_back(seq);
}
vector<int> seq;
for(int n=0; n<x; ++n){
seq.push_back(n*x+n);
}
seqs.push_back(seq);
seq.clear();
for(int n=0; n<x; ++n){
seq.push_back(x-1+n*(x-1));
}
seqs.push_back(seq);
return seqs;
}变得更有功能:
std::vector<std::vector<int>> rules2(const int x){
using namespace std;
vector<vector<int>> seqs;
vector<int> iter(x);
iota(iter.begin(), iter.end(), 0);
for(auto n: iter){
vector<int> seq;
for(auto m: iter){
seq.push_back(n*x+m);
}
seqs.push_back(seq);
}
for(auto n: iter){
vector<int> seq;
for(auto m: iter){
seq.push_back(n+x*m);
}
seqs.push_back(seq);
}
vector<int> seq;
seq.clear();
for(auto n: iter){
seq.push_back(n*x+n);
}
seqs.push_back(seq);
seq.clear();
for(auto n: iter){
seq.push_back(x-1+n*(x-1));
}
seqs.push_back(seq);
return seqs;
}功能方法?(仍然觉得有必要):
std::vector<std::vector<int>> rules1(const int x){
using namespace std;
vector<vector<int>> seqs;
vector<int> iter(x);
iota(iter.begin(), iter.end(), 0);
transform(iter.begin(), iter.end(), back_inserter(seqs), [&](const int& n){
vector<int> seq;
transform(iter.begin(), iter.end(), back_inserter(seq), [&](const int& m){
return n*x+m;
});
return seq;
});
transform(iter.begin(), iter.end(), back_inserter(seqs), [&](const int& n){
vector<int> seq;
transform(iter.begin(), iter.end(), back_inserter(seq), [&](const int& m){
return n+x*m;
});
return seq;
});
vector<int> seq;
transform(iter.begin(), iter.end(), back_inserter(seq), [&](const int& n){
return n*x+n;
});
seqs.push_back(seq);
seq.clear();
transform(iter.begin(), iter.end(), back_inserter(seq), [&](const int& n){
//return (x-n-1)*x+n; // 6,4,2
return x-1+n*(x-1); // 2,4,6
});
seqs.push_back(seq);
return seqs;
}打印时的输出:
rules3
std::vector(0, 1, 2)
std::vector(3, 4, 5)
std::vector(6, 7, 8)
std::vector(0, 3, 6)
std::vector(1, 4, 7)
std::vector(2, 5, 8)
std::vector(0, 4, 8)
std::vector(2, 4, 6)
rules2
std::vector(0, 1, 2)
std::vector(3, 4, 5)
std::vector(6, 7, 8)
std::vector(0, 3, 6)
std::vector(1, 4, 7)
std::vector(2, 5, 8)
std::vector(0, 4, 8)
std::vector(2, 4, 6)
rules1
std::vector(0, 1, 2)
std::vector(3, 4, 5)
std::vector(6, 7, 8)
std::vector(0, 3, 6)
std::vector(1, 4, 7)
std::vector(2, 5, 8)
std::vector(0, 4, 8)
std::vector(2, 4, 6)发布于 2019-07-10 02:18:42
这里有一些建议。这将使用范围-v3库并假定
#include <range/v3/all.hpp>
namespace view = ranges::view;#includes,并提供一个小的测试计划在未来。您可能已经编写了它们,那么为什么不发布它们以节省审阅者的时间呢?int可能太小了。考虑使用std::size_t。您可以为灵活性定义类型别名。使用index_t = std::size_t;std::vector<std::vector<index_t>>类型多次发生。通过使用rule_t = std::vector编写rules_t =std::vector来节省时间;x这个名字有点模糊。size可能更好。rules_t规则(index_t大小){ if ( == 0)抛出std::invalid_argument{“.”};// .}rules(1)当前返回{{0}, {0}, {0}, {0}},这显然是错误的。它应该返回{{0}}。您的一般逻辑是"n行+ n列+ 2对角线“,它只适用于n \ge 2。最简单的方法是特例: rules_t规则(index_t大小){ // .如果(大小为== 1)返回{0}};}view::concat将三个向量连接起来,ranges::to将结果转换为所需的返回类型。(请注意,view::concat禁用了rvalue以防止悬空迭代器,因此我们首先存储子向量。)rules_row函数易于编写: rules_t rules_row(index_t size) {返回视图::ints(index_t(0),size * size)查看::块( size );} view::ints生成一个左包含整数的{0, 1, 2, ..., size * size - 1}序列,view::chunk(size)将其分解为大小为size的每个块。rules_column函数有点棘手,因为Range库没有提供像chunk这样的函数。我们确实有一个函数stride,所以我们可以编写一个手册“循环”:(我花了很长时间才弄明白这一点,所以告诉我是否有更好的方法!)rules_t rules_column(index_t大小){返回视图::ints(index_t(0),size) index_t视图::transform(={返回视图:ints(index_t(Col),size * size)视图::size( size);} view::ints(index_t(0), size)生成列号。他们中的每一个都被传递给羔羊。lambda为每个列返回相应的规则。rules_diagonal函数比较简单: rules_t rules_diagonal(index_t size) {返回{ view::ints(index_t(0),size) ints视图::transform(={返回r* (size + 1);};}),视图:ints(index_t( 1),size +1)\\视图::transform(={返回r* (size - 1);}) };}在这里,我们总是有两个规则:一个用于主对角线{0 * size + 0,1* size + 1,2* size + 2,.,.,(size - 1) * size + (size - 1)},它等价于{0,1,2,……大小- 1} *(大小+ 1);第二对角线{size - 1,2* size - 2,3* size - 3,.大小-(大小- 1)},等于{1,2,3,.,大小+ 1} *(大小- 1)size = 1, 2, 3, ..., 10函数)https://codereview.stackexchange.com/questions/223578
复制相似问题