在我确信已标记的中断/继续是here之后的“nono”时,我需要帮助才能删除代码中的标签。
我有一个方阵和一个长度相同的矢量。向量中已经有一些值,取决于矩阵中的值,循环中的向量发生了变化。
我希望,代码片段基本上是可以理解的......
vectorLoop:
for( int idx = 0; idx < vectorLength; idx++) {
if( conditionAtVectorPosition( v, idx ) ) continue vectorLoop;
matrixLoop:
for( rowIdx = 0; rowIdx < n; rowIdx++ ) {
if( anotherConditionAtVector( v, rowIdx ) ) continue matrixLoop;
if( conditionAtMatrixRowCol( m, rowIdx, idx ) ) continue vectorLoop;
}
setValueInVector( v, idx );
}
请说服我,没有标签的版本更具可读性/更好。
答案 0 :(得分:34)
看看到目前为止提出的解决方案:
它们看起来都不如原作,因为它们涉及在代码机制上花费更多代码而不是算法本身
其中一些已被破坏,或者在编辑之前。最让人沮丧的是,人们不得不非常认真地思考如何在没有标签的情况下编写代码,而不是破坏任何东西。
有些人会因为两次运行相同的测试而受到性能损失,这可能并非总是微不足道。另一种方法是存储和传递圆形布尔值,这很难看。
将代码的相关部分重构为方法实际上是一种无操作:它重新排列代码在文件中的布局方式,但对其执行方式没有影响。
所有这些让我相信,至少在这个问题的情况下,标签是正确的解决方案,不需要重构。当然,有些情况下标签使用不当,应该重构。我不认为它应该被视为一些牢不可破的规则。
答案 1 :(得分:1)
很容易,我的好人。
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 );
}
编辑:很正确你是安德斯。我已经编辑了我的解决方案,也考虑到了这一点。
答案 2 :(得分:1)
@Patrick你假设调用setValueInVector(v,idx);在第二个循环结束时没问题。如果代码在逻辑上相同,则必须将其重写为如下所示:
for( int idx = 0; idx
答案 3 :(得分:1)
阅读您的代码。
所以你可以这样做:
我希望这会有所帮助。
答案 4 :(得分:1)
@ Nicolas
其中一些已被破坏,或者在编辑之前。最诅咒的事实是 人们不得不考虑如何编写没有标签的代码,而不是 打破任何事情。
我有一个不同的观点:其中一些被打破,因为很难弄明白 原算法的行为。
我意识到这是主观的,但我在阅读原始算法时没有任何问题。它比建议的替代品更短更清晰。
此线程中的所有重构都使用其他语言功能模拟标签的行为 - 就好像您将代码移植到没有标签的语言一样。
答案 5 :(得分:1)
有些人会因为两次运行相同的测试而受到性能损失,这可能并不总是微不足道。另一种方法是存储和传递圆形布尔值,这会变得丑陋。性能损失很小。但是我同意两次运行测试不是一个好的解决方案。
我认为问题是如何删除标签,而不是如何优化算法。在我看来,原始海报不知道如何在没有标签的情况下使用“继续”和“破解”关键字,但当然,我的假设可能是错误的。
在性能方面,帖子没有提供有关其他功能实现的任何信息,所以我知道他们也可以通过FTP下载结果,包括编译器内联的简单计算。 / p>
话虽如此,在理论上做两次相同的测试并不是最佳的。
编辑:再想一想,这个例子实际上并不是标签的可怕使用。我同意"goto is a no-no",但不是因为这样的代码。这里使用标签实际上并不会显着影响代码的可读性。当然,它们不是必需的,可以很容易地省略,但不能简单地使用它们,因为“使用标签是坏的”在这种情况下不是一个好的论据。毕竟,删除标签不会使代码更容易阅读,因为其他人已经评论过。
答案 6 :(得分:1)
这个问题不是关于优化算法 - 但无论如何,谢谢;-)
在我写这篇文章时,我认为标记为“继续”是一种可读的解决方案。
我问过question关于Java中标签的约定(标签是否全部大写)。
基本上每个答案都告诉我“不要使用它们 - 总有一种更好的方法!重构!”。所以我发布了这个问题,要求提供更具可读性(因此更好?)的解决方案。
到目前为止,我并不完全相信目前提供的替代方案。
请不要误会我的意思。标签在大多数时候都是邪恶的。
但在我的情况下,条件测试非常简单,算法取自数学论文,因此很可能在不久的将来不会改变。所以我更喜欢一次看到所有相关部分,而不必滚动到另一个名为checkMatrixAtRow(x)的方法。
特别是在更复杂的数学算法中,我发现很难找到“好”的函数名称 - 但我想这是另一个问题
答案 7 :(得分:1)
我认为标记的循环非常罕见,你可以选择任何标记方法为你工作 - 你所拥有的东西使你的意图继续完全清楚。
在主要建议重构原始问题中的循环并现在看到有问题的代码后,我认为你有一个非常易读的循环。
我想象的是一个非常不同的代码块 - 把实际的例子放好,我可以看到它比我想象的要清晰得多。
我为误会道歉。
答案 8 :(得分:0)
这对你有用吗?我将内部循环解压缩为一个方法CheckedEntireMatrix(你可以比我更好地命名) - 而且我的java有点生疏......但我认为它得到了消息
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;
}
答案 9 :(得分:0)
Gishu有正确的想法:
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;
}
答案 10 :(得分:0)
我不太清楚第一次继续理解。 我会复制Gishu并写下类似的内容(抱歉,如果有一些错误):
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;
}
答案 11 :(得分:0)
@ Sadie:
它们看起来都比原来的可读性差,因为它们涉及在代码机制上花费更多代码而不是算法本身
在算法之外外化第二个循环的可读性不一定。如果方法名称选择得当,可以提高可读性。
其中一些已被破坏,或者在编辑之前。最令人沮丧的是,人们不得不非常认真地思考如何在没有标签的情况下编写代码,而不是破坏任何东西。
我有一个不同的观点:其中一些被打破,因为很难弄清楚原始算法的行为。
有些人会因为两次运行相同的测试而受到性能损失,这可能并不总是微不足道。另一种方法是存储和传递圆形布尔值,这很难看。
性能损失很小。但是我同意两次运行测试不是一个好的解决方案。
将代码的相关部分重构为方法实际上是一种无操作:它重新排列代码在文件中的布局方式,但不会影响它的执行方式。
我没有看到这一点。是的,它不会改变行为,比如......重构?
当然,有些情况下标签使用不当,应该重构。我不认为它应该被视为一些牢不可破的规则。
我完全同意。但正如你所指出的那样,我们中的一些人在重构这个例子时遇到了困难。即使最初的例子是可读的,也很难维护。