我相信问题在于如何删除标签,而不是如何优化算法。在我看来,原始发布者没有意识到如何使用没有标签的'continue'和'break'关键字,但是,当然,我的假设可能是错误的。
编辑:再三考虑,该示例实际上并不是对标签的可怕使用。我同意" goto是no-no",但不是因为这样的代码。此处使用标签实际上并不会以很大的方式影响代码的可读性。当然,它们不是必需的,可以轻易省略,但不能仅仅因为"使用标签不好"就不使用它们,在这种情况下,这不是一个好参数。毕竟,像其他人已经提到的那样,删除标签并不能使代码更容易阅读。
Some of them are broken, or were before they were edited. Most damning is the fact that
people are having to think quite hard about how to write the code without labels and not
break anything.
我有不同的观点:其中一些因为难以弄清而破裂了
原始算法的行为。
blockquote>
我意识到这是主观的,但是阅读原始算法没有任何麻烦。它比拟议的替代产品更短,更清晰。
该线程中所有重构的作用是使用其他语言功能来模拟标签的行为-就像您将代码移植到没有标签的语言一样。
通过阅读您的代码。
-
我注意到您消除了conditionAtVectorPosition处的无效矢量位置,然后删除了anotherConditionAtVector处的无效行。
-
似乎检查anotherConditionAtVector上的行是多余的,因为无论idx的值是什么,anotherConditionAtVector仅取决于行索引(假设anotherConditionAtVector没有副作用)。
因此,您可以执行以下操作:
-
首先使用conditionAtVectorPosition(这些是有效列)获取有效位置。
-
然后使用anotherConditionAtVector获取有效行。
-
最后,使用有效列和行使用conditionAtMatrixRowCol。
我希望这有帮助。
@Patrick您假设调用setValueInVector(v,idx);在第二个循环的末尾就可以了。如果代码在逻辑上是相同的,则必须将其重写为如下形式:
轻松,我的好人。
1 2 3 4 5 6 7 8 9 10
| for( int idx = 0; idx < vectorLength; idx++) {
if( conditionAtVectorPosition( v, idx ) ) continue;
for( rowIdx = 0; rowIdx < n; rowIdx++ ) {
if( anotherConditionAtVector( v, rowIdx ) ) continue;
if( conditionAtMatrixRowCol( m, rowIdx, idx ) ) break;
}
if( !conditionAtMatrixRowCol( m, rowIdx, idx ) )
setValueInVector( v, idx );
} |
编辑:完全正确,你是安德斯。我还对解决方案进行了编辑,以考虑到这一点。
@Sadie:
They all look less readable than the original, in that they involve spending more code on the mechanism of the code rather than on the algorithm itself
将第二个循环外部化到算法外部不一定可读性较低。如果方法名称选择正确,则可以提高可读性。
Some of them are broken, or were before they were edited. Most damning is the fact that people are having to think quite hard about how to write the code without labels and not break anything.
我有不同的观点:其中一些被破坏是因为很难弄清楚原始算法的行为。
Some come with a performance penalty of running the same test twice, which may not always be trivial. The alternative to that is storing and passing round booleans, which gets ugly.
性能损失很小。但是我同意两次运行测试不是一个好的解决方案。
Refactoring the relevant part of the code into a method is effectively a no-op: it rearranges how the code is laid out in the file, but has no effect on how it's executed.
我不明白这一点。是的,它不会改变行为,例如...重构?
Certainly there are cases where labels are used incorrectly and should be refactored away. I just don't think it should be treated as some unbreakable rule.
我完全同意。但是正如您所指出的那样,我们中有些人在重构此示例时遇到了困难。即使最初的示例可读,也很难维护。
我不太确定首先要了解什么。
我会复制Gishu并写类似(如果有一些错误,抱歉):
1 2 3 4 5 6 7 8 9 10 11
| for( int idx = 0; idx < vectorLength; idx++) {
if( !conditionAtVectorPosition( v, idx ) && CheckedEntireMatrix(v))
setValueInVector( v, idx );
}
inline bool CheckedEntireMatrix(Vector v) {
for(rowIdx = 0; rowIdx < n; rowIdx++)
if ( !anotherConditionAtVector(v,rowIdx) && conditionAtMatrixRowCol(m,rowIdx,idx) )
return false;
return true;
} |
Gishu有一个正确的主意:
1 2 3 4 5 6 7 8 9 10 11 12 13
| for( int idx = 0; idx < vectorLength; idx++) {
if (!conditionAtVectorPosition( v, idx )
&& checkedRow(v, idx))
setValueInVector( v, idx );
}
private boolean checkedRow(Vector v, int idx) {
for( rowIdx = 0; rowIdx < n; rowIdx++ ) {
if( anotherConditionAtVector( v, rowIdx ) ) continue;
if( conditionAtMatrixRowCol( m, rowIdx, idx ) ) return false;
}
return true;
} |
这对您有用吗?我将内部循环提取到CheckedEntireMatrix方法中(您可以命名比我更好)-另外,我的Java有点生锈。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| for( int idx = 0; idx < vectorLength; idx++) {
if( conditionAtVectorPosition( v, idx )
|| !CheckedEntireMatrix(v)) continue;
setValueInVector( v, idx );
}
private bool CheckedEntireMatrix(Vector v)
{
for( rowIdx = 0; rowIdx < n; rowIdx++ ) {
if( anotherConditionAtVector( v, rowIdx ) ) continue;
if( conditionAtMatrixRowCol( m, rowIdx, idx ) ) return false;
}
return true;
} |