|
|
#1
|
|||
|
|||
выбор операторов
Вариантов выбора очень много , более 100 , есть две переменные по которым надо будет выбрать
Если взять оператор if then , if (a=0) and (b=1) then то смущает что вариантов более ста. Но если взять оператор Case of , то там проверка двух переменных нельзя, но он бы и работал быстрее. Подскажите есть еще варианты для двух переменных? Или только if then ? |
#2
|
||||
|
||||
использовать простую ХЭШ функцию и оператор CASE
Код:
function MySimpleHash(a, b: Byte): Word; begin Result := (a shl 8) or b; end; ... case MySimpleHash(a, b) of ... ... ... ... end; ... Грамотно поставленный вопрос содержит не менее 50% ответа. Грамотно поставленная речь вызывает уважение, а у некоторых даже зависть. |
#3
|
|||
|
|||
Цитата:
Это сначало надо высчетать самому что переменные выдают? Код:
begin ShowMessage(IntToStr(MySimpleHash(26, 49))); case MySimpleHash(26, 49) of 6705:ShowMessage('26-49'); end; end; |
#4
|
|||
|
|||
можно высчитать, можно просто функцию попроще использовать:
Код:
function MyCalcHash(a, b : byte) : Integer; begin Result := a*1000 + b; end; Код:
MyCalcHash(1,1) = 1001 MyCalcHash(10,8) = 10008 и т.д. А вообще, я бы подумал над динамическим выполением этого условия. Все, конечно, зависит от того, что конкретно надо делать в зависимости от значений a & b. Если просто присвоить значение какой-нить переменной или вызвать СТАНДАРТНУЮ функцию, то городить огород смыла нет. А вот если надо выполнить свой код, причем довольно объемный, да еще и в программе этот case при стандартном сценарии использования исполняется многократно, то тогда можно заморочиться с более динамической штукой. Как сделать: 1. Пишем базовый класс: Код:
interface type TDynamicActionBase = class protected procedure DoExecute; virtual; abstract; function CanExecute(a, b : byte) : Boolean; virtual; abstract; public function Execute(a, b : byte): Boolean; procedure Register(AList : TObjectList); end; implementation procedure TDynamicActionBase.Register(AList : TObjectList); begin AList.Add(Self); end; function TDynamicActionBase.Execute(a, b : Byte) : Boolean; begin Result := CanExecute(a,b); If Result Then DoExecute; end; 2. Теперь для каждого реального действия "рожаем" наследника и перекрываем у него соотв. методы: Код:
interface type TDynamicAction_1_1 = class(TDynamicActionBase) protected procedure DoExecute; override; function CanExecute(a, b : byte) : Boolean; override; end; TDynamicAction_2_2 = class(TDynamicActionBase) protected procedure DoExecute; override; function CanExecute(a, b : byte) : Boolean; override; end; implementation procedure TDynamicAction_1_1.DoExecute; begin ShowMessage('1-1'); // Просто для демонстрации end; function TDynamicAction_1_1.CanExecute(a, b : byte) : Boolean; begin Result := (a = 1) and (b = 1); end; procedure TDynamicAction_2_2.DoExecute; begin ShowMessage('2-2'); // Просто для демонстрации end; function TDynamicAction_2_2.CanExecute(a, b : byte) : Boolean; begin Result := (a = 2) and (b = 2); end; 3. Теперь нам надо наши классы зарегистрировать в списке: Код:
interface var DynamicActionList : TObjectList; initialization DynamicActionList := TObjectList.Create(True); TDynamicAction_1_1.Create.Register(DynamicActionList); TDynamicAction_2_2.Create.Register(DynamicActionList); finalization FreeAndNil(DynamicActionList); end. 4. Ну и последний штрих. Надо написать процедуру-выполнятель (функцию, если ничего не нашлось, то она вернет False, если что-то нашлось - то True) Код:
interface function ExecuteDynamicAction(a,b : byte) : Boolean; implementation function ExecuteDynamicAction(a,b : byte) : Boolean; var I : Integer; begin Result := False; For I := 0 To DynamicActionList.Count-1 Do begin Result := (DynamicActionList[i] As TDynamicActionBase).Execute(a,b); If Result Then Break; end; end; ЗЫ. Если хочется действия развести по разным модулям, то тогда прямое обращение к списку действий надо заменить на использование фабрики, а описание DynamicActionList перенести в секцию implementation. DynamicActionList д.б. синглтоном. Последний раз редактировалось lmikle, 09.01.2017 в 23:17. |
#5
|
||||
|
||||
Господа, вы это серьёзно?
Почему не так? Код:
def is_passed(a, b, c, d): if a == c and b == d: return True else: return False Да ито, так слишком надумано, достаточно кортеж (a, b) проверить на вхождение в список кортежей возможных вариантов. Код:
>>> foo = [(1, 2), (3, 4), (5, 6)] >>> foo [(1, 2), (3, 4), (5, 6)] >>> a = (3, 4) >>> a in foo True >>> (1, 2) in foo True >>> (1, 3) in foo False З.Ы. Собственно Финн дал код той же сути, только он оперировал произведением чисел, а не кортежем. — Как тебя понимать? — Понимать меня не обязательно. Обязательно меня любить и кормить вовремя. На Delphi, увы, больше не программирую. Рекомендуемая литература по программированию Последний раз редактировалось M.A.D.M.A.N., 10.01.2017 в 14:59. |
#6
|
|||
|
|||
Mad,
1. Изначально вопрос был в том, как не писать бесконечно длинный список if'ов. Ну и можно ли заменить его на case, если надо делать выбор по нескольким переменным. Базовый ответ - использовать хэш. Дальше я просто спроектировал чуть более гибкую системку, так, для фана. 2. Не знаю как остальные, а я просто уже начал "извращаться". Ну интересно мне было накидать макет такой маленькой подсиситемки. |
Эти 3 пользователя(ей) сказали Спасибо lmikle за это полезное сообщение: | ||