在C ++中有条件地从1..n或n..1迭代
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在C ++中有条件地从1..n或n..1迭代相关的知识,希望对你有一定的参考价值。
我有一个看起来像这样的代码:
bool var = some condition...
if( var )
{
for( int i=0; i<10; ++i )
{
//execute some code ...
}
}
else
{
for( int i=9; i>=0; --i )
{
//execute some other code...
}
}
但是,需要在for循环中执行的代码几乎完全相同,所以我不想写两次。我知道我可以这样做:
bool var = some condition...
for( int i = (var ? 0 : 9 ); (var ? i<10 : i>=0 ); (var ? ++i : --i ) )
{
//Execute my code
}
但这是一个非常优雅的解决方案。
这样做有一个简短,更优雅的方式吗?我检查了std :: iterator,但我认为这不是我需要的。
你在这里专注于错误的问题。如果你有一个方向标志,那么不要把迭代变量全部挂起,确切地说是正确的。只需按要求解释它:
for (int i = 0; i < n; ++i)
{
int j = var ? i : n - 1 - i;
// j goes from 0..n-1 or n-1..0
}
除非您正在进行数十亿次这些调用,否则次要变量的开销将无关紧要。
您可以将循环体转换为函数/方法,并传递足够的上下文以使操作发生。如果循环体主要使用this
上的字段,那么使它成为一种方法应该相当容易。否则,您不需要比当前循环更多的参数。
如果你正在使用C ++ 11,你可以将它实现为一个捕获任何必要信息的lambda,并从每个循环中调用lambda(以便没有松散的函数)。但是,使用可以独立测试的功能或方法是一个好主意。
循环中的代码是否依赖于迭代器的值,如果是,如何?您可以巧妙地使用一些基本数学,例如将开始/结束转换为始终为1..n,或使用abs
和negatives。这会让你有一个循环,并且将主体移动到一个函数中并不是绝对必要的。
想要最小化重复代码是明智之举,但这并不意味着您的解决方案需要适合一行。只需以有意义且清晰易读的方式写出逻辑。包括评论,以解释你的内容和原因。
bool var = some condition...
int start = 0;
int end = 9;
int increment = 1;
if (!var)
{
// Reverse direction
start = 9;
end = 0;
increment = -1;
}
// Loop (forwards if var; reversed if !var)
for (int i = start; i != end; i += increment)
{
}
你可以使用类似的东西。
for(int j = 0; j < 10; ++j) { // always increases
int i = var ? j : 10 - 1 - j;
//go
}
这看起来像是对我的迭代,所以让我们尝试编写一个可以帮助我们的函数:
void incr(int& i) { ++i; }
void decr(int& i) { --i; }
template <typename Iter, typename Incr>
void do_work(Iter start, Iter finish, Incr incr)
{
for(Iter i = start, i != finish; incr(i))
{
// Do your code.
}
}
bool var = some condition...
if( var )
{
do_work(0, 10, &incr);
}
else
{
do_work(9, -1, &decr);
}
以上是关于在C ++中有条件地从1..n或n..1迭代的主要内容,如果未能解决你的问题,请参考以下文章