если оператор с оператором 'или' дает разные результаты при смене условий - PullRequest
0 голосов
/ 04 мая 2018

Я использую strfind со сравнением 'или', например:

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

>> yes!

Оператор if должен оцениваться как true, поскольку отображается yes!.

Напротив, MATLAB не возвращает yes!, если операторы поменялись местами:

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

Почему?

Ответы [ 2 ]

0 голосов
/ 04 мая 2018

Оба следующих условия являются пустыми []:

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

Как указано в ответе Андер , оператор | использует короткое замыкание , чтобы пропустить оценку второго условия, если первое является ложным (или пустым).

Некоторая быстрая отладка даст вам лучшее понимание, если мы проигнорируем короткое замыкание:

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

В обоих случаях вы делаете «если пусто или не ноль», что является пустым, а «if []» ложно (этот условный оператор не будет выполнен).

То, что вы хотите использовать, чтобы быть явным, выглядит примерно так:

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

Здесь мы гарантируем, что все, что оценивается в операторе if, является булевой переменной, а не пустым или возвращает индекс, такой как strfind, поэтому неожиданные результаты менее вероятны.

Существуют более простые методы, такие как strcmp или ismember, если ваши строки должны точно соответствовать. Или contains, если у вас R2016b или новее:

if contains('hello', {'hello','hi'})
    disp('yes!');
end
0 голосов
/ 04 мая 2018

Это из-за короткого замыкания. Короткозамкнутые логические операторы позволяют ускорить код. Вы можете иметь

if veryShort | superlongComputation

так что MATLAB сначала оценивает veryShort, и если это правда, тогда нет необходимости оценивать вторую! Условие if уже выполнено.

В вашем случае strfind(name,'hello') возвращает 1, но strfind(name,'hi') возвращает [].

В первом примере, когда первое вычисленное значение возвращает 1, вы попадаете на экран. Однако во втором случае он возвращает [], поэтому MATLAB оценивает вторую вещь в if и возвращает 1. Затем MATLAB применяет операции or, где [] | 1 - это 0x0 empty logical array, поэтому if не соответствует действительности.

Обратите внимание, что обычно вы хотите использовать || для принудительного короткого замыкания, но | также делает это, если оно находится внутри while или if:

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

...