Модераторы: Snowy, MetalFan, bems, Poseidon

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Перечисляемые типы, математические операции 
V
    Опции темы
ALeXandrK
  Дата 17.8.2007, 16:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 342
Регистрация: 31.1.2007
Где: Санкт-Петербург

Репутация: 1
Всего: 6



Возможно ли оптимизировать данный код:

Код

...
TWeekDays = set of (wdMo, wdTu, wdWe, wdTh, wdFr, wdSa, wdSu);
...
var 
      StudingDays: TWeekDays;
begin
  if cbMo.Checked then
    StudingDays := StudingDays + [wdMo]
  else
    StudingDays := StudingDays - [wdMo];
  ...
end;


Таких проверок получается 7 (для каждого дня недели) и мне кажется, что можно это дело упростить,
но как?

Если есть интересные материалы/ссылки по работе со множествами, пишите.

Это сообщение отредактировал(а) ALeXandrK - 17.8.2007, 16:42


--------------------
Богат не/ни тот, у кого много, а тот, кому хватает
PM WWW   Вверх
sentry
Дата 17.8.2007, 16:32 (ссылка) |  (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Code Monkey
*


Профиль
Группа: Участник
Сообщений: 133
Регистрация: 29.1.2007
Где: Москва

Репутация: нет
Всего: 10



А это разве перечислимый (я так называю) тип? Это вроде же множество. А перечислимый это
Код

TWeekDays = (wdMo, wdTu, wdWe, wdTh, wdFr, wdSa, wdSu);


А упростить можно вроде так:
Код

var
  X: TWeekDays;
begin
  X := [];
  if CheckBox1.Checked then
    X := X + [wdMo];
  if CheckBox1.Checked then
    X := X + [wdTu];
  // ...
end;

PM MAIL   Вверх
ALeXandrK
Дата 17.8.2007, 16:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 342
Регистрация: 31.1.2007
Где: Санкт-Петербург

Репутация: 1
Всего: 6



Да... ошибся - это и вправду множества. Жаль я тему не могу переименовать smile 

sentry: так я уже упростил, но все равно спасибо.

Я имел ввиду, что может можно написать что-то вроде:
Код

StudingDays := StudingDays + [wdMo]*Ord(cbMo.Checked);


Но так не выходит... а по мысли, Ord переводит значение Cheked (boolean) в 1 или 0, и
тогда при умножении мы добавляем значение в множество или нет соответственно.


Это сообщение отредактировал(а) ALeXandrK - 17.8.2007, 16:50


--------------------
Богат не/ни тот, у кого много, а тот, кому хватает
PM WWW   Вверх
Rennigth
Дата 17.8.2007, 17:02 (ссылка) |   (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1708
Регистрация: 21.6.2004
Где: Moscow

Репутация: 15
Всего: 76



В твоем случае без if не обойтить. Другие варианты будут еще белее громоздкие. Но есть симпотичные функции Include  и Exclude, которые повысят как утверждает борланд эффектифность кода:
Цитата

In Delphi code, Include adds the element I to the set S. The expression Include(S,I) corresponds to S := S + [I] but the Include procedure generates more efficient code.
S is a set type variable, and I is an expression of a type compatible with the base type of S. 

Код

TWeekDays = set of (wdMo, wdTu, wdWe, wdTh, wdFr, wdSa, wdSu);
...
var 
  StudingDays: TWeekDays;
begin
  if cbMo.Checked then
    Include(StudingDays, wdMo)  
  else
    Exclude(StudingDays, wdMo);
  ...
end;



--------------------
(* Honesta mors turpi vita potior *)
PM MAIL ICQ   Вверх
ALeXandrK
Дата 17.8.2007, 17:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 342
Регистрация: 31.1.2007
Где: Санкт-Петербург

Репутация: 1
Всего: 6



Rennigth: про Include  и Exclude - хорошее замечание. Тоже читал про них в Help, но что-то даже и не задумался применять smile 
Руки то уже прикипели к + smile 


--------------------
Богат не/ни тот, у кого много, а тот, кому хватает
PM WWW   Вверх
sentry
Дата 17.8.2007, 17:06 (ссылка)  | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Code Monkey
*


Профиль
Группа: Участник
Сообщений: 133
Регистрация: 29.1.2007
Где: Москва

Репутация: нет
Всего: 10



Цитата(ALeXandrK @  17.8.2007,  18:13 Найти цитируемый пост)
 Ord переводит значение Cheked (boolean) в 1 или 0, итогда при умножении мы добавляем значение в множество или нет соответственно.

Ord то переводит, только операции умножения мн-ва на число нет.

А если так:
Код

TEnum = (Nothing1, wdMo, Nothing2, wdTu, Nothing3, wdWe, Nothing4, wdTh, Nothing5, wdFr, Nothing6, wdSa, Nothing7, wdSu);
TWeekDays = set of TEnum;

//...

var
  X: TWeekDays;
begin
    X := X + [TEnum(Ord(CheckBox1.Checked))];
    X := X + [TEnum(Ord(CheckBox2.Checked)+2)];
end;


Извиняюсь, поправил, но все-таки if больше нравится smile 
Потом только проверять нужное в in, а на Nothing не обращать внимание.

Это сообщение отредактировал(а) sentry - 17.8.2007, 17:27
PM MAIL   Вверх
ALeXandrK
Дата 17.8.2007, 17:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 342
Регистрация: 31.1.2007
Где: Санкт-Петербург

Репутация: 1
Всего: 6



sentry: красиво, но не работает smile 


--------------------
Богат не/ни тот, у кого много, а тот, кому хватает
PM WWW   Вверх
sentry
Дата 17.8.2007, 17:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Code Monkey
*


Профиль
Группа: Участник
Сообщений: 133
Регистрация: 29.1.2007
Где: Москва

Репутация: нет
Всего: 10



Цитата(ALeXandrK @  17.8.2007,  18:41 Найти цитируемый пост)
 красиво, но не работает  

Я уже понял smile Эх, если бы Nothing Как-нибудь убрать или закономерность какую-нибудь найти. И цикл еще присобачить smile
PM MAIL   Вверх
ALeXandrK
Дата 17.8.2007, 17:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 342
Регистрация: 31.1.2007
Где: Санкт-Петербург

Репутация: 1
Всего: 6



Цитата(sentry @ 17.8.2007,  17:20)
Эх, если бы Nothing Как-нибудь убрать или закономерность какую-нибудь найти. И цикл еще присобачить smile

sentry: но это уже не оптимизация, а нагромажедение получется smile 


--------------------
Богат не/ни тот, у кого много, а тот, кому хватает
PM WWW   Вверх
EvilsInterrupt
Дата 17.8.2007, 18:12 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


Профиль
Группа: Завсегдатай
Сообщений: 1019
Регистрация: 14.7.2007
Где: Железнодорожный, МО, Россия

Репутация: нет
Всего: 9



1)
В Пачеко книга по дельфи 5 том 1 на стр. 93, сказано, что юзать надо Include\Exclude реализуеются 1 маш. командой, когда +\- 13 + 6*n (6 кол-во битов во множестве). Вывод: надо проверить код генерируемый компиллером
2)
Код

  procedure TfrmMain.Button1Click(Sender: TObject);
  var
    tmp : TCheckBoxVariantSet;
  begin
    tmp := []; // выключаем все нафиг, чтобы недалать лишних else
    if CheckBox1.Checked then Include(tmp,var1);
    if CheckBox2.Checked then Include(tmp,var2);
    if CheckBox3.Checked then Include(tmp,var3);
    if CheckBox4.Checked then Include(tmp,var4);
    if CheckBox5.Checked then Include(tmp,var5);
    if CheckBox6.Checked then Include(tmp,var6);
    if CheckBox7.Checked then Include(tmp,var7);
    end;
  end;


и на такой код:
Код

    X := X + [TEnum(Ord(CheckBox1.Checked))];
    X := X + [TEnum(Ord(CheckBox2.Checked)+2)];

я бы не стал закладываться, т.к. выигрышь в скорости небольшой, а при измении кодогенерации разработчиком дельфи могут появится - трудно уловимые баги.

Это сообщение отредактировал(а) EvilsInterrupt - 17.8.2007, 18:31
PM MAIL WWW ICQ Jabber   Вверх
sentry
Дата 17.8.2007, 20:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Code Monkey
*


Профиль
Группа: Участник
Сообщений: 133
Регистрация: 29.1.2007
Где: Москва

Репутация: нет
Всего: 10



Цитата(EvilsInterrupt @  17.8.2007,  19:42 Найти цитируемый пост)
В Пачеко книга по дельфи 5 том 1 на стр. 93, сказано, что юзать надо Include\Exclude реализуеются 1 маш. командой, когда +\- 13 + 6*n (6 кол-во битов во множестве). Вывод: надо проверить код генерируемый компиллером

Посмотрел.

Тут записываем wdNo в eax с занулением старших битов. В Ebx ранее было загружено пустое множество.
Далее, логично делаем "или" ( al - 8 бит (256) ). Поскольку результат сейчас в eax, заносим его в ebx.
Код

Unit1.pas.34: X := X + [wdMo];
004540E8 0FB605FC404500   movzx eax,[$004540fc]
004540EF 0AC3             or al,bl
004540F1 8BD8             mov ebx,eax


И вот:
Код

Unit1.pas.34: Include(X, wdMo);
004540E8 80CB01           or bl,$01



Цитата(EvilsInterrupt @  17.8.2007,  19:42 Найти цитируемый пост)
выигрышь в скорости небольшой

С if побыстрее будет...

PM MAIL   Вверх
EvilsInterrupt
Дата 17.8.2007, 21:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


Профиль
Группа: Завсегдатай
Сообщений: 1019
Регистрация: 14.7.2007
Где: Железнодорожный, МО, Россия

Репутация: нет
Всего: 9



Я пока не вижу конкурентов моему варианту, но он получился благодаря книге Пачеко, так что это не мой! ;)
Можно ли еще вот в чем загадка для ума? ))) и знать ответ хочется, будем головоломствовать далее
PM MAIL WWW ICQ Jabber   Вверх
ALeXandrK
  Дата 17.8.2007, 22:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 342
Регистрация: 31.1.2007
Где: Санкт-Петербург

Репутация: 1
Всего: 6



Цитата(EvilsInterrupt @ 17.8.2007,  21:26)
... будем головоломствовать далее...

Раз к простой мат. операции свести не удается, то думаю, что вариант
Код

tmp := []; // выключаем все нафиг, чтобы недалать лишних else
    if CheckBox1.Checked then Include(tmp,var1);



Самый оптимальный. 

Тему считаю решенной, но новым вариантам будем рады smile 


--------------------
Богат не/ни тот, у кого много, а тот, кому хватает
PM WWW   Вверх
MetalFan
Дата 19.8.2007, 10:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 22
Всего: 128



можно мой вариант) может и работать будет помедленнее, но тут скорость вроде бы и не нужна
1. объявляем типы:
Код

TWeekDay = (wdMo, wdTu, wdWe, wdTh, wdFr, wdSa, wdSu);
TWeekDays = set of TWeekDay;

2. проставить в Tag TCheckBox'ам Ord значение TWeekDay при создании формы или в дизайне.
Код

procedure TForm1.OnCreate...
begin
  chkb1.Tag : = ord( wdMo );
...
  chkb7.Tag : = ord( wdSu );
end;

3. затем можно сделать либо так:
3.1 Всем чекам назначить один OnClick и...
Код

...
  if TCheckBox( Sender ).Checked then
    Include( FCheckedDays, TWeekDay(TCheckBox( Sender ).Tag)
  else
    Exclude( FCheckedDays, TWeekDay(TCheckBox( Sender ).Tag)

3.2 либо в цикле такимже образом "собрать" данные... разве что для удобства можно в OnCreate формы засунуть чеки в массив


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
EvilsInterrupt
Дата 19.8.2007, 10:53 (ссылка)   | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


Профиль
Группа: Завсегдатай
Сообщений: 1019
Регистрация: 14.7.2007
Где: Железнодорожный, МО, Россия

Репутация: нет
Всего: 9



MetalFan, Не есть гуд! Много не нужных действий, а ведь программер существо ленивое! Да и если говороить про дизайн тайм, то сво-во компонентов tag, в исходник u_main.pas или др. не положится, а это опять dfm или др. файлы таскать за собой, Зачем?! Неее я протев ;)))

Это сообщение отредактировал(а) EvilsInterrupt - 19.8.2007, 10:54
PM MAIL WWW ICQ Jabber   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Для новичков"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0567 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.