嵌套函数中间隔的多个 CASE 语句 [英] multiple CASE statements on interval within nested functions

查看:17
本文介绍了嵌套函数中间隔的多个 CASE 语句的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

虽然我想出了一个使用多个 if/else if 语句的解决方法,但我很想知道我的 case 语句看起来有什么问题,如下图所示:

Although I have come up with a work-around using multiple if / else if statements, I am curious in knowing what looks wrong with my case statements, illustrated below:

function [ar_vo,bucket] = revEng(v)
...
s=solve(solve>0) * sqrt(T); 
ar_vo=s; 
bucket=ri(ar_vo);
%%%%%%%%%%%%%%%%%%%%%
function bucket = ri(ar_vo)
%          switch(ar_vo)
%              case ((ar_vo >= 0)&&(ar_vo < 0.005)) (1)
%                   bucket=1;
%              case ((ar_vo >= 0.005)&&(ar_vo < 0.02)) (2)
%                   bucket=2;
%              case ((ar_vo >= 0.02)&&(ar_vo < 0.05)) (3)
%                   bucket=3;
%              case ((ar_vo >= 0.05)&&(ar_vo < 0.1)) (4)
%                   bucket=4;
%              case ((ar_vo >= 0.1)&&(ar_vo < 0.15)) (5)
%                   bucket=5;
%              case ((ar_vol >= 0.15)&&(ar_vol < 0.25)) (6)
%                   bucket=6;
%              case (ar_vo >= 0.25)                     (7)
%                   bucket=7;
%              otherwise
%                   error('MATLAB:RI Bucket:NotAvailable.'); (8)
%          end
%      

给定 ar_vo = 0.073... 在调试代码时,由于某些原因它会跳过 case (4) 并到达 case (8)...

Given ar_vo = 0.073... while debugging the code, it skips case (4) for some reasons and reaches case (8)...

低效但可行的解决方案,带有多个 if/else if:

    if ((ar_vo >= 0)&&(ar_vo < 0.005))
            bucket=1;
          else if ((ar_vo >= 0.005)&&(ar_vo < 0.02))
                 bucket=2;
              else if ((ar_vo >= 0.02)&&(ar_vo < 0.05))
                     bucket=3;
                  else if ((ar_vo >= 0.05)&&(ar_vo < 0.1))
                        bucket=4;
                      else if ((ar_vo >= 0.1)&&(ar_vo < 0.15))
                           bucket=5;
                          else if ((ar_vo >= 0.15)&&(ar_vo < 0.25))
                               bucket=6;
                              else if (ar_vo >= 0.25)
                                 bucket=7;
                                  else 
                                      error('MATLAB:RI Bucket:NotAvailable.');
                                  end
                              end
                          end
                      end
                  end
              end
          end

推荐答案

switch 语句的 case 表达式 不能是 MATLAB 中的条件.它们必须是.

The case expressions for your switch statement cannot be conditionals in MATLAB. They must be values.

switch thing
    case 1
        % do thing
    case {2, 3}
        % do other thing
    otherwise
end

那么 MATLAB 在您的情况下所做的是将您的条件 转换为 值.因此,当您提供 0.073 的值时,MATLAB 看到的是这个.

So what MATLAB is doing in your case, is that it is converting your conditionals into values. So when you supply a value of 0.073 what MATLAB sees is this.

switch 0.73
    case 0
    case 0
    case 0
    case 1
    case 0
    case 0
    case 0
    otherwise
end

由于 0.73 显然不匹配任何那些您落入 otherwise 并收到错误的值.

Since 0.73 obviously doesn't match any of those values you fall through to the otherwise and receive the error.

这就是为什么 switch 语句实际上只最适合用于将输入值与 exact 可能值进行比较的分类数据(显然不适合浮点数).

This is why switch statements are really only best for categorical data where you are comparing the input value against exact possible values (obviously not good for a floating point number).

如果您真的想将其保留为 switch 语句,您可以做一些小把戏,实际上让您的 switch 表达式简单地1"(true) 它将按照您的意愿行事.

If you REALLY want to keep this as a switch statement you could do a little trickery and actually make your switch expression simply "1" (true) and it will behave as you want it to.

switch(1)
    case ((ar_vo >= 0)&&(ar_vo < 0.005))
        bucket=1;
    case ((ar_vo >= 0.005)&&(ar_vo < 0.02))
        bucket=2;
    case ((ar_vo >= 0.02)&&(ar_vo < 0.05))
        bucket=3;
    case ((ar_vo >= 0.05)&&(ar_vo < 0.1))
        bucket=4;
    case ((ar_vo >= 0.1)&&(ar_vo < 0.15))
        bucket=5;
    case ((ar_vo >= 0.15)&&(ar_vo < 0.25))
        bucket=6;
    case (ar_vo >= 0.25)
        bucket=7;
    otherwise
        error('MATLAB:RI Bucket:NotAvailable.');
end

请不要实际上这样做.

一个理智的方法是使用一系列 if/elseif 语句(与您的 if else if 语句的长树相反).这是一个很好的方法(并且非常适合浮点数),因为它只是检查该数字是否在给定范围内.

One sane approach is to use a series of if/elseif statements (as opposed to your long tree of if else if statements). This is a good approach (and is well-suited to floating point numbers) as it simply checks if that number is within a given range.

if ((ar_vo >= 0)&&(ar_vo < 0.005))
    bucket=1;
elseif ((ar_vo >= 0.005)&&(ar_vo < 0.02))
    bucket=2;
elseif ((ar_vo >= 0.02)&&(ar_vo < 0.05))
    bucket=3;
elseif ((ar_vo >= 0.05)&&(ar_vo < 0.1))
    bucket=4;
elseif ((ar_vo >= 0.1)&&(ar_vo < 0.15))
    bucket=5;
elseif ((ar_vo >= 0.15)&&(ar_vo < 0.25))
    bucket=6;
elseif (ar_vo >= 0.25)
    bucket=7;
else 
    error('MATLAB:RI Bucket:NotAvailable.');
end

最佳解决方案

个人会做的是删除所有代码并简单地用以下语句替换它.

The Best Solution

What I personally would do though, would be to remove all of that code and simply replace it with the following statements.

lowerlimits = [0, 0.005, 0.02, 0.05, 0.1, 0.15, 0.25]
upperlimits = [lowerlimits(2:end), inf];

bucket = find(ar_vo >= lowerlimits & ar_vo < upperlimits);

if isempty(bucket)
    error('MATLAB:RI Bucket:NotAvailable.');
end

在这种方法中,我将 ar_vo 与所有范围 同时 进行比较,然后使用匹配的索引获取 bucket 值.如果没有分配bucket,则没有匹配,bucket是一个空数组.

In this approach I compare ar_vo to all ranges simultaneously and then get the bucket value by using the index of the match. If there was no bucket assigned, there was no match, and bucket is an empty array.

这大大减少了复制/粘贴错误的机会,并且如果您想在以后修改条件更容易.特别是对于必须遍历整个 if/elseif 构造的 > 0.25 的值,它可能也更高效.

This drastically reduces the chance of copy/paste errors and makes it easier if you want to modify the conditions at a later date. It is likely also more performant particularly for values > 0.25 which would have to traverse your entire if/elseif construct.

这篇关于嵌套函数中间隔的多个 CASE 语句的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆