обнаружение 4 перестановок 2 значений переменных в операторе switch case
У меня есть 2 переменные, width
и height
в виде целых чисел. Любой из них может быть положительным или отрицательным (не нулевым). Поэтому, естественно, есть 4 случая;
width > 0 && height > 0
width > 0 && height < 0
width < 0 && height > 0
width < 0 && height < 0
Есть ли способ объединить эти случаи так, чтобы он мог быть поставлен как простой switch case
switch( aggregate ){
case 1:
case 2:
case 3:
case 4:
}
Если нет лучшего способа, чем использовать if
для каждый тогда в трехмерном пространстве у вас будет 3 длины (x,y,z)
и будет 27 if
блоков.
Я используюjavascript , если это имеет значение.
5 ответов:
В javascript это довольно просто, Просто переверните условие вверх ногами:
switch(true) { case (width > 0 && height > 0): break; case (width > 0 && height < 0): break; case (width < 0 && height > 0): break; case (width < 0 && height < 0): break; default: }
Это также работает в VB6/VBA, но не во многих других языках, таких как C++ и C#.
Вот простое доказательство: http://jsfiddle.net/avuxj/
Вы можете рассматривать каждое из ваших условий (ширина положительная, высота положительная) как один логический атрибут и объединить их в двоичное число и переключиться на него.
Псевдокод:
int v = (width > 0 ? 0 : 1) << 1 | (height > 0 ? 0 : 1) << 0; switch (v) { case 0b00: // width < 0 && height < 0; break; case 0b01: // width < 0 && height > 0; break; case 0b10: // width > 0 && height < 0 break; case 0b11: // width > 0 && height > 0 break; }
Если выбранный вами язык не содержит двоичных числовых литералов, то он не так удобочитаем, но вы можете исправить это с помощью комментариев.
Также обратите внимание, что языки, которые поддерживают интерпретацию
true
как1
иfalse
как0
, помогут сделать строкуint v = ...
короче.
Вы могли бы сделать
Хотя все это немного сбивает с толку. (Особенно если у вас есть 3 значения). Вы можете использовать переменные, чтобы сделать ваш код немного понятнее.var bits=0; if(width > 0) { bits+=1; } if(height > 0) { bits+=2; } switch{bits} { case 0: //both negative //something break; case 1: //width positive, height negative //something break; case 2: //width negative, height positive //something break; case 3: //both positive //something break; }
Я бы сказал, что это не помогает сделать код намного яснее.var WIDTH_POSITIVE_BIT=1; var HEIGHT_POSITIVE_BIT=2; var bits=0; if(width > 0) { bits+=WIDTH_POSITIVE_BIT; } if(height > 0) { bits+=HEIGHT_POSITIVE_BIT; } switch{bits} { case 0: //both negative //something break; case WIDTH_POSITIVE_BIT: //width positive, height negative //something break; case HEIGHT_POSITIVE_BIT: //width negative, height positive //something break; case WIDTH_POSITIVE_BIT+HEIGHT_POSITIVE_BIT: //both positive //something break; }
Не могу сделать это, не добавив немного накладных расходов.
s = ( width < 0 ) ? 0 : 1; s += ( height < 0 ) ? 0 : 2; switch(s) { case 0: // 00 => both < 0 case 1: // 01 => width > 0, height < 0 case 2: // 10 => width < 0, height > 0 case 3: // 11 => both > 0 }
И это может работать для 3D-случая:
s = ( width < 0 ) ? 0 : 1; //First bit for width s += ( height < 0 ) ? 0 : 2; //Second bit for height s += ( depth < 0 ) ? 0 : 4; //Third bit for depth switch(s) { case 0: // 0 0 0 case 1: // 0 0 1 case 2: // 0 1 0 case 3: // 0 1 1 case 4: // 1 0 0 case 5: // 1 0 1 case 6: // 1 1 0 case 7: // 1 1 1 }
Конечно, предполагая, что у вас не может быть измерения 0.
Несколько ответов являются логически правильными. Если бы вы делали это в C, это было бы:
s = ((width<0)<<1) | (height<0); switch(s) { .... }
Это может сделать огромную разницу. У меня есть код, который объединяет 9 условий в такой переключатель. Переключатель превращается в таблицу переходов и работает намного быстрее, чем оценка множества условий. Там нет ветвления, только таблица прыжков. Хотя я не могу говорить ни с чем java или Java script.
Вы также можете сделать вложенные операторы if:
if (witdh<0) { if (height<0) { // both negative } else { // only width negative } } else { if (height<0) { // only height negative } else { // both positive } }
Я нахожу, что растирание биты условий вместе и с помощью переключателя, чтобы быть более читаемым - особенно если число условий растет.