OberonCore https://forum.oberoncore.ru/ |
|
Убираю LOOP'ы https://forum.oberoncore.ru/viewtopic.php?f=82&t=2547 |
Страница 3 из 5 |
Автор: | Александр Ильин [ Пятница, 23 Апрель, 2010 10:54 ] |
Заголовок сообщения: | Re: Убираю LOOP'ы |
Опять непонятно, зачем LOOP: Код: found := FALSE; Нетрудно увидеть, что при выходе found = ~A. Это же просто линейный поиск:LOOP IF A THEN EXIT ELSIF B THEN found := TRUE; EXIT END; Step; END; (* loop *) IF ~found THEN SomeCode; END; Код: WHILE ~A & ~B DO Переменная found не понадобилась.
Step; END; IF A THEN SomeCode; END; |
Автор: | Info21 [ Пятница, 23 Апрель, 2010 12:01 ] |
Заголовок сообщения: | Re: Убираю LOOP'ы |
Александр Ильин писал(а): Опять непонятно, зачем LOOP: Просто могучий, но девственный интеллект наладился орудовать узловатой дубиной. Откуда знать партизану про боевые искусства.
|
Автор: | Geniepro [ Пятница, 23 Апрель, 2010 12:25 ] |
Заголовок сообщения: | Re: Убираю LOOP'ы |
Так все эти LOOP'ы написаны Стефаном Мейтцлером, которого тут приводили как пример профессионала, заработавшего миллионы программированием на Обероне? |
Автор: | Александр Ильин [ Пятница, 23 Апрель, 2010 16:48 ] |
Заголовок сообщения: | Re: Убираю LOOP'ы |
Поиск элемента последовательность с номером index (index >= 0). Код: PROCEDURE DoSomething (index: INTEGER); Преобразуем в WHILE по привычной схеме:VAR n: INTEGER; BEGIN n := 0; LOOP IF A THEN EXIT ELSIF n = index THEN OneShotCode; EXIT END; INC (n); Step; END; END DoSomething; Код: PROCEDURE DoSomething (index: INTEGER); Убираем лишнюю локальную переменную:VAR n: INTEGER; BEGIN n := 0; WHILE ~A & ~(n = index) DO INC (n); Step; END; IF ~A THEN OneShotCode; END; END DoSomething; Код: PROCEDURE DoSomething (index: INTEGER); Насколько я знаю, проверка на равенство нулю выполняется быстрее, чем сравнение двух произвольных чисел.
BEGIN WHILE ~A & ~(index = 0) DO DEC (index); Step; END; IF ~A THEN OneShotCode; END; END DoSomething; |
Автор: | Info21 [ Пятница, 23 Апрель, 2010 18:42 ] |
Заголовок сообщения: | Re: Убираю LOOP'ы |
Александр Ильин писал(а): Насколько я знаю, проверка на равенство нулю выполняется быстрее, чем сравнение двух произвольных чисел. В реале этого не измерить, но без лишней переменной код проще.
|
Автор: | Александр Ильин [ Понедельник, 31 Май, 2010 18:59 ] |
Заголовок сообщения: | Re: Убираю LOOP'ы |
Код: WHILE ~A DO Эквивалентно следующему коду:IF Found() THEN RETURN TRUE END; Step(); END; RETURN FALSE Код: WHILE ~A & ~Found() DO
Step(); END; RETURN ~A |
Автор: | Александр Ильин [ Понедельник, 12 Июль, 2010 18:27 ] |
Заголовок сообщения: | Re: Убираю LOOP'ы |
Исходный LOOP с тремя EXIT'ами. Задача - организовать цикл обработки сообщений для модального окна с некоторыми дополнительными проверками при нажатии кнопки "OK" (SomeCheckIfOk). "ptr" - некая переменная, заданная до цикла: Код: LOOP Для начала удалим самый внутренний EXIT:cmd := GetCmd (); IF cmd = Commands.Ok THEN IF SomeCheckIfOk () THEN SomeCode1 (); IF ptr = NIL THEN EXIT END; SomeCode2 (ptr); EXIT END; DoOnOk (); ELSIF cmd = Commands.Cancel THEN DoOnCancel (); EXIT END; (* if cmd *) END; Код: LOOP Выносим из цикла всё, что будет выполняться лишь один раз:cmd := GetCmd (); IF cmd = Commands.Ok THEN IF SomeCheckIfOk () THEN SomeCode1 (); IF ptr # NIL THEN SomeCode2 (ptr); END; EXIT END; DoOnOk (); ELSIF cmd = Commands.Cancel THEN DoOnCancel (); EXIT END; (* if cmd *) END; Код: cmd := GetCmd (); UPD: Забыл 'DO' после 'WHILE'.
WHILE (cmd # Commands.Cancel) & ~((cmd = Commands.Ok) & SomeCheckIfOk ()) DO IF cmd = Commands.Ok THEN (* ~SomeCheckIfOk () *) DoOnOk (); END; (* if cmd *) cmd := GetCmd (); END; IF cmd = Commands.Cancel THEN DoOnCancel (); ELSE (* (cmd = Commands.Ok) & SomeCheckIfOk () *) SomeCode1 (); IF ptr # NIL THEN SomeCode2 (ptr); END; END; (* if cmd *) |
Автор: | Александр Ильин [ Вторник, 08 Февраль, 2011 14:54 ] |
Заголовок сообщения: | Re: Убираю LOOP'ы |
Задача: найти последний элемент цепочки объектов. Если последний элемент - составной (тип Values.Struct), то углубиться в него и найти последний там. Если там в конце тоже составной элемент, ещё раз углубиться, и так далее, пока не будет найден самый последний в самой глубине. Код с LOOP/EXIT: Код: LOOP IF v.next = NIL THEN IF (v IS Values.Struct) & (v (Values.Struct).parts # NIL) THEN v := v (Values.Struct).parts; (* recurse into substructure *) ELSE EXIT END END; v := v.next; END; После преобразования текст сократился на 2 строки: Код: REPEAT Попутно устранена ошибка лишнего "v := v.next" после захода в подструктуру в первом варианте кода. Если эту же ошибку устранить в первом варианте, добавив ELSE ко внешнему IF, то получим выигрыш уже в 3 строки.
WHILE v.next # NIL DO v := v.next; END; (* find last *) IF (v IS Values.Struct) & (v (Values.Struct).parts # NIL) THEN v := v (Values.Struct).parts; (* recurse into substructure *) END; UNTIL v.next = NIL; |
Автор: | Info21 [ Вторник, 08 Февраль, 2011 15:02 ] |
Заголовок сообщения: | Re: Убираю LOOP'ы |
Как насчет цикла Дейкстры: Код: WHILE v.next # NIL DO
v := v.next; ELSIF (v IS Values.Struct) & (v (Values.Struct).parts # NIL) DO v := v (Values.Struct).parts; (* recurse into substructure *) END; |
Автор: | Peter Almazov [ Вторник, 08 Февраль, 2011 15:54 ] |
Заголовок сообщения: | Re: Убираю LOOP'ы |
Александр Ильин писал(а): После преобразования текст сократился на 2 строки: Насколько я понял, этот код вообще неправильный. Пусть после v := v (Values.Struct).parts оказывается, что v.next = NIL. В этом случае нужно опять смотреть на parts, а не отваливать в строке UNTIL v.next = NIL.
Код: REPEAT Попутно устранена ошибка лишнего "v := v.next" после захода в подструктуру в первом варианте кода. Если эту же ошибку устранить в первом варианте, добавив ELSE ко внешнему IF, то получим выигрыш уже в 3 строки.WHILE v.next # NIL DO v := v.next; END; (* find last *) IF (v IS Values.Struct) & (v (Values.Struct).parts # NIL) THEN v := v (Values.Struct).parts; (* recurse into substructure *) END; UNTIL v.next = NIL; |
Автор: | Александр Ильин [ Вторник, 08 Февраль, 2011 16:18 ] |
Заголовок сообщения: | Re: Убираю LOOP'ы |
Info21 писал(а): Как насчет цикла Дейкстры Действительно, исходный код после исправления можно представить в видеКод: LOOP Это равнозначно кодуIF v.next = NIL THEN IF (v IS Values.Struct) & (v (Values.Struct).parts # NIL) THEN v := v (Values.Struct).parts; (* recurse into substructure *) ELSE EXIT END ELSE v := v.next; END; END; Код: LOOP А это уже с очевидностью цикл Дейкстры. Спасибо за подсказку. : )
IF v.next # NIL THEN v := v.next; ELSIF (v IS Values.Struct) & (v (Values.Struct).parts # NIL) THEN v := v (Values.Struct).parts; (* recurse into substructure *) ELSE EXIT END; END; |
Автор: | Александр Ильин [ Вторник, 08 Февраль, 2011 16:29 ] |
Заголовок сообщения: | Re: Убираю LOOP'ы |
Peter Almazov писал(а): Насколько я понял, этот код вообще неправильный. Вы правы, спасибо. Преобразование я сделал правильно, но в исходном коде ошибка, это да. Просто, видимо, в реальном применении не сталкивались. (Специфика данных. По той же причине и лишний переход на v.next не мешал.)
|
Автор: | Info21 [ Вторник, 08 Февраль, 2011 20:53 ] |
Заголовок сообщения: | Re: Убираю LOOP'ы |
Александр Ильин писал(а): А это уже с очевидностью цикл Дейкстры. Либо полный проход, либо линейный поиск, либо аккуратненький Дейкстра. Исключений пока не встречал.
|
Автор: | Peter Almazov [ Вторник, 08 Февраль, 2011 21:04 ] |
Заголовок сообщения: | Re: Убираю LOOP'ы |
Info21 писал(а): Либо полный проход, либо линейный поиск, либо аккуратненький Дейкстра. Исключений пока не встречал. Тяжелый случай.Ну вот здесь "распознайте" viewtopic.php?f=27&t=2981 |
Автор: | Info21 [ Вторник, 08 Февраль, 2011 22:07 ] |
Заголовок сообщения: | Re: Убираю LOOP'ы |
Peter Almazov писал(а): Тяжелый случай. Это типа "Дурак."?
|
Автор: | Александр Шостак [ Вторник, 08 Февраль, 2011 22:28 ] |
Заголовок сообщения: | Re: Убираю LOOP'ы |
В тему к циклам. Попал на днях в руки свежий белорусский учебник по информатике за 9-й класс. Ориентация - Pascal.ABC. Первая конструкция - FOR. Далее тема линейного поиска. Если хотите найти определённый элемент, то выходите из цикла по условию: Код: FOR i:=0 TO ... DO
IF A[i] = искомое THEN BREAK; |
Автор: | Peter Almazov [ Вторник, 08 Февраль, 2011 22:50 ] |
Заголовок сообщения: | Re: Убираю LOOP'ы |
Info21 писал(а): Либо полный проход, либо линейный поиск, либо аккуратненький Дейкстра. Исключений пока не встречал. Info21 писал(а): Это типа "Дурак."? Типа, встретьте исключений.
|
Автор: | Info21 [ Среда, 09 Февраль, 2011 06:15 ] |
Заголовок сообщения: | Re: Убираю LOOP'ы |
Peter Almazov писал(а): Info21 писал(а): Это типа "Дурак."? Типа, встретьте исключений. |
Автор: | Сергей Губанов [ Среда, 09 Февраль, 2011 14:32 ] |
Заголовок сообщения: | Re: Убираю LOOP'ы |
Info21 писал(а): Александр Ильин писал(а): А это уже с очевидностью цикл Дейкстры. Либо полный проход, либо линейный поиск, либо аккуратненький Дейкстра. Исключений пока не встречал. |
Автор: | Info21 [ Среда, 09 Февраль, 2011 15:11 ] |
Заголовок сообщения: | Re: Убираю LOOP'ы |
Сергей Губанов писал(а): Info21 писал(а): Александр Ильин писал(а): А это уже с очевидностью цикл Дейкстры. Либо полный проход, либо линейный поиск, либо аккуратненький Дейкстра. Исключений пока не встречал.Код-то самый короткий и ясный |
Страница 3 из 5 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |