Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 09.01.2017, 16:42
Мих123456 Мих123456 вне форума
Прохожий
 
Регистрация: 07.01.2017
Сообщения: 6
Версия Delphi: delphi 7
Репутация: 10
По умолчанию выбор операторов

Вариантов выбора очень много , более 100 , есть две переменные по которым надо будет выбрать
Если взять оператор if then , if (a=0) and (b=1) then то смущает что вариантов более ста. Но если взять
оператор Case of , то там проверка двух переменных нельзя, но он бы и работал быстрее. Подскажите есть
еще варианты для двух переменных? Или только if then ?
Ответить с цитированием
  #2  
Старый 09.01.2017, 17:06
Аватар для dr. F.I.N.
dr. F.I.N. dr. F.I.N. вне форума
I Like it!
 
Регистрация: 12.12.2009
Адрес: Россия, г. Новосибирск
Сообщения: 660
Версия Delphi: D6/D7
Репутация: 26643
По умолчанию

использовать простую ХЭШ функцию и оператор CASE
Код:
function MySimpleHash(a, b: Byte): Word;
begin
  Result := (a shl 8) or b;
end;

...
case MySimpleHash(a, b) of
...
...
...
...
end;
...
__________________
Грамотно поставленный вопрос содержит не менее 50% ответа.
Грамотно поставленная речь вызывает уважение, а у некоторых даже зависть.
Ответить с цитированием
  #3  
Старый 09.01.2017, 17:18
Мих123456 Мих123456 вне форума
Прохожий
 
Регистрация: 07.01.2017
Сообщения: 6
Версия Delphi: delphi 7
Репутация: 10
По умолчанию

Цитата:
Сообщение от dr. F.I.N.
использовать простую ХЭШ функцию и оператор CASE
Код:
function MySimpleHash(a, b: Byte): Word;
begin
  Result := (a shl 8) or b;
end;

...
case MySimpleHash(a, b) of
...
...
...
...
end;
...

Это сначало надо высчетать самому что переменные выдают?

Код:
begin
  ShowMessage(IntToStr(MySimpleHash(26, 49)));
case MySimpleHash(26, 49) of
 6705:ShowMessage('26-49');

end;


end;
Ответить с цитированием
  #4  
Старый 09.01.2017, 20:24
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,004
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

можно высчитать, можно просто функцию попроще использовать:
Код:
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  
Старый 10.01.2017, 14:53
Аватар для M.A.D.M.A.N.
M.A.D.M.A.N. M.A.D.M.A.N. вне форума
Sir Richard Abramson
 
Регистрация: 05.04.2008
Сообщения: 5,505
Версия Delphi: XE10
Репутация: выкл
По умолчанию

Господа, вы это серьёзно?
Почему не так?
Код:
def is_passed(a, b, c, d):
    if a == c and b == d:
        return True
    else:
        return False
Ну и проверять на пересечении множеств (a, b).

Да ито, так слишком надумано, достаточно кортеж (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  
Старый 10.01.2017, 19:55
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,004
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Mad,
1. Изначально вопрос был в том, как не писать бесконечно длинный список if'ов. Ну и можно ли заменить его на case, если надо делать выбор по нескольким переменным. Базовый ответ - использовать хэш. Дальше я просто спроектировал чуть более гибкую системку, так, для фана.
2. Не знаю как остальные, а я просто уже начал "извращаться". Ну интересно мне было накидать макет такой маленькой подсиситемки.
Ответить с цитированием
Эти 3 пользователя(ей) сказали Спасибо lmikle за это полезное сообщение:
Admin (11.01.2017), dr. F.I.N. (11.01.2017), M.A.D.M.A.N. (10.01.2017)
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра
Комбинированный вид Комбинированный вид

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 10:57.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter