debug记录:三目运算符优先级的问题

leetcode 188.买卖股票最佳时机Ⅳ

错误代码:

class Solution {
public:
    int maxProfit(int k, vector<int>& prices) {
        if(prices.size()==1) return 0;
        vector<vector<int>>dp(prices.size(),vector<int>(2*k+1,0));
        //初始化
        for(int i=1;i<=2*k;i++){
            dp[0][i]=(i%2==0)?0:-prices[0];
        }
        //递推
        for(int i=1;i<prices.size();i++){
            for(int j=1;j<=2*k;j++){
                dp[i][j]=max(dp[i-1][j],dp[i-1][j-1]+(j%2==0)?prices[i]:-prices[i]);
            }
        }
        return *max_element(dp[prices.size()-1].begin(),dp[prices.size()-1].end());
    }
};

出现了解答错误:
在这里插入图片描述

这段代码查了很久也没有查出问题,最后发现问题出在整个三目运算符的大括号上。

在 C++、Java、JavaScript 等语言中,三元运算符 ? : 的优先级低于加法和减法。也就是说先执行加减运算,最后才执行三目运算符

原代码:

dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - 1] + (j % 2 == 0) ? prices[i] : -prices[i]);

这种情况下,三元运算符并没有正确地应用在 prices[i] 和 -prices[i] 上,而是应用在了 dp[i - 1][j - 1] + (j % 2 == 0)prices[i] 之间,因为加法操作符的优先级高于三元运算符,所以三目运算符是最后执行的!

所以,如果 j % 2 == 0 为真,那么整个表达式的结果就会是 dp[i - 1][j - 1] + (j % 2 == 0),否则为 -prices[i]。显然这并不符合逻辑,因为我们希望在 j % 2 == 0 为真的情况下,结果应该是 prices[i],否则为 -prices[i]。

修改为:

dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - 1] + (j % 2 == 0 ? prices[i] : -prices[i]));

这种写法才是正确方式,三元运算符 ? : 正确地应用在了 prices[i] 和 -prices[i] 上。这个表达式的结果会是 dp[i - 1][j - 1] 加上 prices[i](如果 j % 2 == 0 为真)或 -prices[i](如果 j % 2 == 0 为假)。

总结,应该使用括号确保三元运算符的优先级。否则,如果按照第一种写法,由于运算符的优先级问题,三元运算符最后才执行,会造成很难看出来的逻辑错误。

三元运算符最前面的条件需不需要加括号的问题

j % 2 == 0 ? prices[i] : -prices[i]

这里面的 %、== 和 ?: 都是运算符,他们的优先级分别是: % > == > ?:。所以在此情况下,其实并不需要对 j % 2 == 0 进行单独的括号处理,因为 % 的优先级本来就高于 ==== 的优先级又高于 ?:

但是在整个表达式 dp[i - 1][j - 1] + (j % 2 == 0 ? prices[i] : -prices[i]) 中,由于 + 的优先级高于 ?:,所以必须用括号将三元运算符的内容括起来,以确保按照预期进行计算。

一般来说,当涉及多个运算符,且运算符之间的优先级有差异时,需要使用括号表明表达式的计算顺序,且括号位置需要注意。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值