gpt4 book ai didi

c# - 有效地用代码表达2x2逻辑网格

转载 作者:太空狗 更新时间:2023-10-29 22:17:39 26 4
gpt4 key购买 nike

在事件处理程序中,我正在响应值的更改。我可以访问旧值和新值,并希望根据更改的内容执行某些操作。
每个不同的结果都将执行一些操作/函数x、y或z的组合。z接受一个介于-1和1之间的参数。执行这些操作的顺序并不重要。
看看下面的逻辑网格。旧值是标签的最左边一列,新值是标签的最上面一行:

          New:
0 !=0
-------- -------
Old: 0 | nothing Y, Z(1)
!=0 | X, Z(-1) X, Y -- Z(0) is okay but not required for this quadrant

有什么好的方式来代表这一点呢?
我在C_工作,但会接受任何语言的答案,因为这不是真正的语言问题-我可以翻译任何东西。
例子:
if (oldvalue == 0 && newvalue == 0) return;
if (oldvalue != 0) X();
if (newvalue != 0) Y();
Z(oldvalue != 0 ? -1 : 0 + newvalue != 0 ? 1 : 0);

我想那看起来不错,但还有其他办法可以做到。
int which = (oldvalue == 0 ? 0 : 1) + (newvalue == 0 ? 0 : 2)

switch (which) {
case 1:
X(); Z(-1);
break;
case 2:
Y(); Z(1);
break;
case 3:
X(); Y();
break;
}

事实上,这是一个比我现在处理的稍微简单一点的案子。在OldValue和NewValue不为零且彼此相等的情况下,将NewValue视为0。
请随意回答给定的问题或附加的约束条件。还有一点,但我觉得一开始就太多了。如果之后的事情看起来很有趣,我将在这里或在一个新问题中介绍其余的内容。
我想我之所以问这个问题是因为我经常会遇到这些逻辑网格,它们并不总是2x2,有时它们会大一点。很高兴注意到我可以用整个“条纹”来处理一些响应,比如每次看到旧值时都会注意到x!=0,但似乎我开始遇到一个模式,它要求一些表达逻辑更一般地处理它,而不是费力地将其转换为if-then-else语句。我的意思是,如果我能提供一种逻辑网格,让编译器找出处理它的最佳方法,那就太酷了。
只是做些疯狂的头脑风暴:
Conditions:
oldvalue == 0 ? 0 : 1
newvalue == 0 ? 0 : 2

Actions:
X = {false, true, false, true}
Y = {false, false, true, true}
Z(-1) = true where condition = 1
Z(1) = true where condition = 2

你有什么想法?我会奖励任何实质性的参与。

最佳答案

让我们从另一个角度来看你的问题。在设计代码体时,我尝试应用以下原则:
纠正错误。
说清楚。
使它简洁。
快点。
…按顺序。
所有这些,在某种程度上,都是主观的。然而,通情达理的人往往会找到共同点——而且人们往往对他们的对立观点有更多的共识。但撇开这些…
这里的首要任务是确保代码能够正常工作。显然,有多个实现可以实现这一点——但我还要补充一点,很重要的是,要容易证明实现是正确的。实现这一点的一种方法是使代码读起来更像规范(稍后将详细介绍)。
第二个优先事项是确保在将来,当开发人员(包括原始作者!)看看这段代码,他们马上就能理解它在做什么。实现越复杂(读:fancy),开发人员就越难立即理解代码在做什么。
第三个优先——简短、简洁的代码,是与前两个部分相反的代码。希望使代码更简洁,可能会导致您使用比实际解决问题所需的更复杂的构造。虽然保持代码简短很重要,但我们不应该让它变得难以理解的密集。
最后一个优先级-性能-只在重要的时候才重要。我的意思是,从性能的角度来看,您不应该使实现复杂化,除非您已经执行了概要分析并将其识别为系统中的瓶颈。
因此,既然我们已经研究了驱动我们决策的原则,让我们将它们应用到手头的问题上。您已经提供了一个非常清晰的代码行为规范。让我们试着坚持下去:

void YourMethod( int oldValue, int newValue )
{
bool oldValueNonZero = oldValue != 0;
bool newValueNonZero = newValue != 0;

if( oldValueNonZero ) { X(); }
if( newValueNonZero ) { Y(); }
if( oldValueNonZero && newValueNonZero ) { Z(); }
}

所以为什么我喜欢这个特殊的实现。让我们把它分解。
首先,请注意,我选择创建临时布尔值来捕获测试新旧值是否为非零的结果。通过捕获这些值,我避免了多次执行计算,还使代码更具可读性(见下文)。
其次,通过选择描述性名称 oldValueNonZeronewValueNonZero我使实现清楚地表明了我的期望。这既提高了代码的可读性,也清楚地向将来必须阅读代码的开发人员传达了我的意图。
第三,注意 if()测试的主体被包装在 {}括号中,这有助于减少将来对实现所做的更改将破坏行为的可能性,例如意外地包含一个新的案例。使用单行 ifs是解决未来问题的方法。
最后,我不会试图缩短比较并提前退出函数。如果性能非常重要,早期退出可能是有用的。但是,如果只有一个退出点(1),那么它更容易理解方法的行为。
这段代码符合规范的要求吗?我相信是的。
它容易阅读和理解吗?至少在我看来,我会说是的。
这段代码是使逻辑短路的最简洁或最复杂的方法吗?几乎肯定不是……但在我看来,这不仅仅是其他品质的弥补。
你是否喜欢这种特殊的代码结构在某种程度上取决于你的品味和风格。但我希望我所阐述的关于我如何组织它的原则能帮助你在未来做出这样的决定。
您已经指出,您有时会遇到类似的“逻辑网格”问题,但这些问题的案例数量更多。这类问题之所以复杂,有两个原因:
参数可以采用的值的数量会增加-它们可以采用一般形式 MxN
维度的数量增加了-换句话说,规则中要包含更多的变量: MxNxOxP...xZ
问题的一个广义解决方案(如另一个响应所示)是将解决方案编码为多维矩阵-并为每种情况定义一组操作。然而,规则完全有可能重叠——为了简单起见,可能需要将等价的案例折叠在一起。
我对处理一般案件的反应是…这要看情况。如果条件可以减少到一些非常小的情况,那么命令式if/else逻辑可能仍然是解决问题的最佳方法。如果条件的数目非常大,那么使用声明式方法可能会有意义,在这种方法中,您可以使用某种查找表或矩阵来对案例进行编码。
1>-只有一个方法只有一个退出点的原则的一个常见例外是前提条件。通过首先检查所有/任何先决条件避免失败和退出(如果该方法被违反),则更能避免嵌套和反向逻辑。

关于c# - 有效地用代码表达2x2逻辑网格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3587147/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com