我有一个代表特殊文件格式的类。它存储3D空间的离散化数据。我想在屏幕上打印数据。但问题是,我必须以给定的任意顺序打印数据。
我的班级是这样的:
class MyFile
{
public:
// ...
enum SEQUENCE
{
SEQ_I = 200,
SEQ_J = 201,
SEQ_K = 202
};
enum INCREMENT
{
PLUS = 300,
MINUS = 301
};
double GetVariable(uint64_t i, uint64_t j, uint64_t k) const;
std::vector<SEQUENCE> Sequences;
std::vector<INCREMENT> Increments;
friend std::ostream & operator<<(std::ostream & os, const MyFile & mf);
// ...
private:
// ...
std::vector<double> Data;
// ...
}
我这样用:
MyFile myfile;
// ...
// Load some data to "myfile".
// ...
myfile.Sequences.push_back(MyFile::SEQUENCE::SEQ_J);
myfile.Sequences.push_back(MyFile::SEQUENCE::SEQ_I);
myfile.Sequences.push_back(MyFile::SEQUENCE::SEQ_K);
myfile.Increments.push_back(MyFile::INCREMENT::MINUS);
myfile.Increments.push_back(MyFile::INCREMENT::MINUS);
myfile.Increments.push_back(MyFile::INCREMENT::PLUS);
std::cout << myfile;
上面提到的for循环就是这个方法:
std::ostream & operator<<(std::ostream & os, const MyFile & mf)
{
// The loop variables.
uint64_t InnerMin = 0;
uint64_t MiddlMin = 0; // I spelled it "middl" to make
uint64_t OuterMin = 0; // the all variable names same length.
uint64_t InnerMax = 0;
uint64_t MiddlMax = 0;
uint64_t OuterMax = 0;
uint64_t InnerIndex = 0;
uint64_t MiddlIndex = 0;
uint64_t OuterIndex = 0;
uint64_t *i = &InnerIndex;
uint64_t *j = &MiddlIndex;
uint64_t *k = &OuterIndex;
int8_t InnerIncrement = +1;
int8_t MiddlIncrement = +1;
int8_t OuterIncrement = +1;
// Find out the variable of the out-most loop.
switch (mf.Sequences[0])
{
default:
case MyFile::SEQUENCE::SEQ_I:
i = &OuterIndex;
OuterMin = mf.IndexIMin;
OuterMax = mf.IndexIMax;
break;
case MyFile::SEQUENCE::SEQ_J:
j = &OuterIndex;
OuterMin = mf.IndexJMin;
OuterMax = mf.IndexJMax;
break;
case MyFile::SEQUENCE::SEQ_K:
k = &OuterIndex;
OuterMin = mf.IndexKMin;
OuterMax = mf.IndexKMax;
break;
}
break;
switch (mf.Increments[0])
{
case MyFile::INCREMENT::PLUS:
OuterIncrement = +1;
break;
case MyFile::INCREMENT::MINUS:
OuterIncrement = -1;
break;
}
break;
// The middle loop.
switch (mf.Sequences[1])
{
case MyFile::SEQUENCE::SEQ_I:
i = &MiddlIndex;
MiddlMin = mf.IndexIMin;
MiddlMax = mf.IndexIMax;
break;
default:
case MyFile::SEQUENCE::SEQ_J:
j = &MiddlIndex;
MiddlMin = mf.IndexJMin;
MiddlMax = mf.IndexJMax;
break;
case MyFile::SEQUENCE::SEQ_K:
k = &MiddlIndex;
MiddlMin = mf.IndexKMin;
MiddlMax = mf.IndexKMax;
break;
}
break;
switch (mf.Increments[1])
{
case MyFile::INCREMENT::PLUS:
MiddlIncrement = +1;
break;
case MyFile::INCREMENT::MINUS:
MiddlIncrement = -1;
break;
}
// The inner loop.
switch (mf.Sequences[2])
{
case MyFile::SEQUENCE::SEQ_I:
i = &InnerIndex;
InnerMin = mf.IndexIMin;
InnerMax = mf.IndexIMax;
break;
case MyFile::SEQUENCE::SEQ_J:
j = &InnerIndex;
InnerMin = mf.IndexJMin;
InnerMax = mf.IndexJMax;
break;
default:
case MyFile::SEQUENCE::SEQ_K:
k = &InnerIndex;
InnerMin = mf.IndexKMin;
InnerMax = mf.IndexKMax;
break;
}
break;
switch (mf.Increments[2]) // The third (inner) increment.
{
case MyFile::INCREMENT::PLUS:
InnerIncrement = +1;
break;
case MyFile::INCREMENT::MINUS:
InnerIncrement = -1;
break;
}
// Run the loop.
for (uint64_t OuterIndex=OuterMin; OuterIndex<=OuterMax; OuterIndex += OuterIncrement)
{
for (uint64_t MiddlIndex=MiddlMin; MiddlIndex<=MiddlMax; MiddlIndex += MiddlIncrement)
{
for (uint64_t InnerIndex=InnerMin; InnerIndex<=InnerMax; InnerIndex += InnerIncrement)
{
os << GetVariable(*i, *j, *k) << "\t";
}
}
os << std::endl;
}
return os;
}
这是操纵循环次序的正确方法吗?我发现我实施的方式太长而且复杂。有没有更好的方法呢?
答案 0 :(得分:1)
改进代码的最简单方法是创建一个辅助函数getNextCoordinate
,它接受一个坐标和顺序的元组(三元组),以给定的顺序返回下一个元组。加函数getInitialCoordinates
,给出给定订单的初始坐标。