如何解决三元运算在八度中有效吗?
问题 是三元运算有效,因为我无法在网上找到任何与其相关的文档。而且我还发现在 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
运算符的一个重点是表达式 expr1
和 expr2
的计算。如果 condition
为 true
,则不得评估 expr2
;如果 condition
为 false
,则不得评估 expr1
。在像 ifelse/merge
这样的函数中,两个表达式在传递给函数之前都会被求值,所以 ifelse
不应被视为真正的三元 if
运算符。
有一些基于 MATLAB 的实现 here 和 here 用于创建递归匿名函数。诀窍是表达式由 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 举报,一经查实,本站将立刻删除。