微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

三元运算在八度中有效吗?

如何解决三元运算在八度中有效吗?

问题 是三元运算有效,因为我无法在网上找到任何与其相关的文档。而且我还发现在 MATLAB 中不可能使用三元,因此这里将不胜感激任何建议和答案。

#三元运算代码

taxes = (income > 50000)*(((income-50000) * 0.20)+(0.10*50000)) + (~(income > 50000))*0.10 *50000
#Condition True and this computation False then this computation

#Code with if and else

if (income) > 50000
#income = income - 50000
#Taxed at 10% (i.e 0.10) for $ 50000
#taxes = 50000 * 0.10
#Rest income will be Taxed at 20% (i.e 0.20)
taxes = 50000 * 0.10 + ((income-50000) * 0.20)
else
#Taxed at 10% (i.e 0.10)
taxes = income * 0.10
endif

输出

GNU Octave,version 6.1.0
copyright (C) 2020 The Octave Project Developers.
This is free software; see the source code for copying conditions.
There is ABSOLUTELY NO WARRANTY; not even for MERCHANTABILITY or
fitness FOR A PARTIculaR PURPOSE.  For details,type 'warranty'.

Octave was configured for "x86_64-w64-mingw32".

Additional information about Octave is available at https://www.octave.org.

Please contribute if you find this software useful.
For more information,visit https://www.octave.org/get-involved.html

Read https://www.octave.org/bugs.html to learn how to submit bug reports.
For information about changes from prevIoUs versions,type 'news'.

>> income = 60000;
>> compute_taxes
taxes = 7000
>> income = 50000;
>> compute_taxes
taxes = 5000
>>

解决方法

任何语言中三元运算符的任何定义与 if 语句之间存在一些重要区别。

主要的是后者是一个语句,而三元运算符根据定义是一个表达式。换句话说,您希望它返回一个值。 Octave/matlab 中的 if 块不会“返回”值(即您不能执行 a = if ... endif)。如果您需要“返回”的内容,则需要将其分配给循环内部的外部变量,然后在循环外部使用该变量。

第二件大事是,三元运算符应该可链接。也就是说,您应该能够执行“如果这个,那么那个,否则如果那个,那么那个其他事情”,这样在长比较链的末尾,您将返回一个值。


现在,octave 和 matlab 没有这种运算符。但是在八度中,很容易模拟一个,例如带单元格:

M1 = false; M2 = false; M3 = true;
{'expression1','expression2','expression3','fallback'}([ M1,M2,M3,true ]){1}

如果你真的愿意,你可以把那种东西变成一个很好的匿名函数,它返回第一个掩码/测试为真的表达式:

tern = @(varargin) reshape(varargin,2,[])(2,:)([reshape(varargin,[]){1,:}]){1}
tern( M1,1,3,true,4 )   % ans = 3

其中“回退”是通过在“回退”值之前明确评估为“真”的测试来实现的。

注意:这种在匿名函数内“链接”两个或多个索引操作的风格仅适用于八度音阶,因为不幸的是 matlab 不允许链接操作,例如a(1)(2)。没有什么能阻止你制作一个等效的“适当的”外部函数,你可以在第二次索引它之前将中间结果保存到一个临时变量中;因此,从概念上讲,该策略也适用于 matlab。


或者,您可以使用稍微不同的语法制作一个更简单的“三元运算符”(好吧,函数),其中分别传递“测试/掩码”数组、“表达式”和“回退”单元格。例如

tern2 = @(M,E,F) [E,F]{find([M,true],1)}
tern2( [M1,M3],{1,3},{4} )   % ans = 3

最后还有 ifelse 函数,它在精神上是相似的,即 ifelse(test,expr_if_true,expr_if_false),但这并不是真正的三元运算符/函数,因为它是不可链接的;基于“真/假掩码”在两个选项之间进行选择更有用,例如

ifelse( [M1,{4,5,6} )
% ans = { 4,3 }
,

您可以使用两个短路 if&& 运算符模拟三元 || 运算符。
考虑这个 if/else 语句:

if condition 
    val = expr1;
else
    val = expr2;
end

t 定义为 t = @(x) 1; 并将三元 if 运算符定义为:

condition && t(val = expr1) || t(val = expr2);

实现三元 if 运算符的一个重点是表达式 expr1expr2 的计算。如果 conditiontrue,则不得评估 expr2;如果 conditionfalse,则不得评估 expr1。在像 ifelse/merge 这样的函数中,两个表达式在传递给函数之前都会被求值,所以 ifelse 不应被视为真正的三元 if 运算符。

有一些基于 MATLAB 的实现 herehere 用于创建递归匿名函数。诀窍是表达式由 lambda 包装以防止它们的评估。
考虑以下计算第 n 个斐波那契数的函数:

function val = fib(f,n)
  if n <= 2
    val = 1;
  else
    val = f(f,n - 1) + f(f,n - 2));
end

当前提议的技术可用于将其实现为(在 Octave 6.1.0 上测试):

fib = @(f,n,t = @(x) 1,tmp = n <= 2 && t(val = 1) || t(val = f(f,n - 2))) val;

在递归匿名函数以外的情况下,您可以使用:

val = {condition && t(tmp = expr1) || t(tmp = expr2),tmp}{2};

然而,这些技巧的效果可能不如 if/else 语句。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。