![]() |
|
|
|
|
#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; ... |
|
#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 З.Ы. Собственно Финн дал код той же сути, только он оперировал произведением чисел, а не кортежем. Последний раз редактировалось M.A.D.M.A.N., 10.01.2017 в 14:59. |
|
#6
|
|||
|
|||
|
Mad,
1. Изначально вопрос был в том, как не писать бесконечно длинный список if'ов. Ну и можно ли заменить его на case, если надо делать выбор по нескольким переменным. Базовый ответ - использовать хэш. Дальше я просто спроектировал чуть более гибкую системку, так, для фана. 2. Не знаю как остальные, а я просто уже начал "извращаться". Ну интересно мне было накидать макет такой маленькой подсиситемки. |
| Эти 3 пользователя(ей) сказали Спасибо lmikle за это полезное сообщение: | ||