带有 'or' 运算符的 if 语句在交换条件时给出不同的结果

if statement with 'or' operator gives different results when conditions are swapped

我正在使用 strfind 进行 'or' 比较,如下所示:

name='hello';
if strfind(name,'hello') | strfind(name,'hi')
    disp('yes!')
end

>> yes!

if 语句必须计算为 true,因为显示 yes!

相比之下,MATLAB 不会 return yes! 如果交换语句:

if strfind(name,'hi') | strfind(name,'hello')
    disp('yes!')
end

为什么?

这是因为短路。短路逻辑运算符可以加快代码速度。你可以拥有

if veryShort | superlongComputation

所以 MATLAB 所做的是首先计算 veryShort,如果为真,则无需计算第二个! if 条件已经满足。

在你的情况下 strfind(name,'hello') returns 1,但是 strfind(name,'hi') returns [].

在第一个示例中,作为评估的第一件事 returns 1,您将进入显示。然而在第二种情况下,它是 returns [],因此 MATLAB 计算 if 和 returns 1 中的第二个东西。然后 MATLAB 应用 or 操作,其中 [] | 10x0 empty logical array,因此 if 不正确。

注意,通常你想使用 || 强制短路,但 | 也可以,如果它在 whileif 内:

https://uk.mathworks.com/matlabcentral/answers/99518-is-the-logical-operator-in-matlab-a-short-circuit-operator

以下两个条件都为空[]:

name='hello';
strfind(name,'hello') | strfind(name,'hi'); % = []
strfind(name,'hi') | strfind(name,'hello'); % = []

, the | operator is using short circuiting 中所述,如果第一个条件为假(或空)则跳过对第二个条件的评估。

如果我们忽略短路,一些快速调试会让您更好地理解:

strfind(name,'hi');    % = []
strfind(name,'hello'); % = 1

在这两种情况下,你都在做 "if empty or non-zero",它是空的,“if []”是假的(该条件语句不会被执行)。

你想要明确的是这样的:

if ~isempty(strfind(name, 'hello')) & ~isempty(strfind(name, 'hi'))
    disp('yes!')
end

在这里,我们保证 if 语句中计算的所有内容都是布尔变量,而不是空的或像 strfind returns 这样的索引,因此不太可能出现意外结果。

有更简单的方法,例如如果您的字符串应该完全匹配,则使用 strcmpismember。或者 contains 如果您有 R2016b 或更新版本:

if contains('hello', {'hello','hi'})
    disp('yes!');
end