Forth http://fforum.winglion.ru/ |
|
выдать подстроку из исходной строки http://fforum.winglion.ru/viewtopic.php?f=19&t=1981 |
Страница 2 из 2 |
Автор: | chess [ Пт фев 27, 2009 10:40 ] |
Заголовок сообщения: | |
Alex писал(а): chess, обратите внимание что в Вашем решении мы избавились от жонглирования на стеках,
но осталась сложность с необходимостью контролировать и представлять в голове количество параметров на стеке. Да сложность переползла в другую плоскость. Но это контролируемая сложность и она уберется после именования локальных переменных, введение которого скажется только на времени компиляции, а на времени исполнения нет. Кроме того с именованием локальных переменных появится возможность держать несколько областей локальных переменных, из-за чего необходимость в переименовании ранее введенных локальных переменных отпадет, хотя и это можно делать при измении смысла ранее введенных локальных переменных. В любом случае смысл того или иного параметра определяет программист. Конкретно все это должно вылиться в исключение слов 9|, |9 и Pn, останутся только слова обрамляющие именование параметров на стеке, но за параметрами на стеке все равно следить будет надо. Но такой контроль гораздо проще чем без локальных переменных. Код: : SUBST { a0 u0 a1 u1 a2 u2 -- a3 u3|a0 u0 } Согласитесь, при таком виде записи, сложность резко уменьшилась. Слово |2 оставит на стеке только два нужных параметра, а все параметры трех локусов уберет со стека.
a0 u0 a1 u1 SEARCH { a3 u3 ?3 } a0 u0 a2 u2 SEARCH { a4 u4 ?4 } ?3 ?4 AND IF a3 u1 + DUP a4 - NEGATE ELSE a0 u0 THEN |2 ; Тут переименование ранее введеных локалсов вообще не проводилось. Реальные задачи вряд-ли потребуют число локусов более 10-ти и число локальных переменных более 50-ти, поэтому стек будет небольшой. |
Автор: | Alex [ Пт фев 27, 2009 17:40 ] |
Заголовок сообщения: | |
К сожалению в задании не указал, что в случае если нет совпадения тегов-ограничителей следует вернуть пустую строку и в строке может быть несколько пар тегов. Правильнее с локалсами будет выглядеть так: Код: : SUBST ( a0 u0 a1 u1 a2 u2 -- a u ) 6| P6 P5 P4 P3 SEARCH P3 2OVER P2 P1 SEARCH |7 7| P1 P5 AND IF P7 P4 + P3 OVER - ELSE S" " THEN |2 ; S" ..... <INP=456>..<nn=098>..." S" <INP=" S" >" SUBST TYPE 456 даже в таком виде локалсы вполне полезный инструмент И еще первой ссылкой промазал http://www.ddj.com/architect/210603608 |
Автор: | вопрос [ Пт фев 27, 2009 18:09 ] |
Заголовок сообщения: | |
chess писал(а): Код: : SUBST { a0 u0 a1 u1 a2 u2 -- a3 u3|a0 u0 } Согласитесь, при таком виде записи, сложность резко уменьшилась. a0 u0 a1 u1 SEARCH { a3 u3 ?3 } a0 u0 a2 u2 SEARCH { a4 u4 ?4 } ?3 ?4 AND IF a3 u1 + DUP a4 - NEGATE ELSE a0 u0 THEN |2 ; можно сказать, исчезла, но сколько вариантов пришлось перебрать |
Автор: | Alex [ Сб фев 28, 2009 19:50 ] |
Заголовок сообщения: | |
простите за занудство, а давайте попробуем еще немножко поиграть заметим, что первый поиск должен вернуть адрес после последнего символа первого тега и длину оставшейся строки, выделим это в отдельное слово. От второго поиска требуется в случае удачи только адрес начала, также выделим. Введем вспомагательное словечко |x - сброс стека до инициализации локалсов Код: : |x FIX-SP @ FIX-NPAR @ CELLS + CELL + SP! ; : SEARCH1 ( a0 u0 a1 u1 -- a u ) SEARCH IF P3 P3 NEGATE D+ ELSE |x S" " RDROP THEN ; : SEARCH2 ( a0 u0 a1 u1 -- a ) SEARCH IF DROP ELSE |x S" " RDROP THEN ; : SUBST ( a0 u0 a1 u1 a2 u2 -- a u ) 6| P6 P5 P4 P3 SEARCH1 2DUP P2 P1 SEARCH2 NIP OVER - |2 ; S" ..... <INP=456>..<nn=098>..." S" <INP=" S" >" SUBST Выглядет вроде неплохо, но сложность опять таки перешла в другую плоскость локалсы используются совместно ( почти как регистры ), и каждое из трех слов знает о поведении двух других |
Автор: | mOleg [ Сб фев 28, 2009 21:34 ] |
Заголовок сообщения: | |
Alex писал(а): простите за занудство, а давайте попробуем еще немножко поиграть
заметим, что первый поиск должен вернуть адрес после последнего символа первого тега и длину оставшейся строки, выделим это в отдельное слово. От второго поиска требуется в случае удачи только адрес начала, также выделим. тут надо бы условие задачи более формальное, потому как для выдирание из текста одного числа достаточно решения в лоб, гораздо интереснее, если надо выдирать пары значений <ключ=значение> из текста. и вполне можно обойтись без локалсов |
Автор: | chess [ Пн мар 02, 2009 18:00 ] |
Заголовок сообщения: | |
Сделал локалсы в стеке пока только с одним локусом (для нескольких придется видимо сделать стек для начальных смещений локусов в стеке). В качестве буфера для имен локалсов и их номеров использовал PAD. Код: USER FIX-SP
USER NLOC USER-VALUE DTN : XSP! SP@ NLOC @ + FIX-SP ! ; : PAR FIX-SP @ + @ ; : l{ PAD 100 ERASE 0 NLOC ! PAD TO DTN 0 BEGIN CELL + DUP NextWord 2DUP S" }l" COMPARE 0= IF 2DROP DROP CELL - NLOC ! TRUE ELSE 2DUP DTN SWAP MOVE NIP DTN + TO DTN DTN ! DTN CELL + TO DTN FALSE THEN UNTIL POSTPONE XSP! ; IMMEDIATE : NOTFOUND 2>R PAD 100 2R@ SEARCH 2R@ NIP 2 = AND IF 2R> NIP NIP + @ NEGATE LIT, POSTPONE PAR ELSE 2DROP 2R> NOTFOUND EXIT THEN ; : |N N>R FIX-SP @ SP! NR> DROP ; : SUBST l{ a0 u0 a1 u1 a2 u2 }l a0 u0 a2 u2 SEARCH NIP \ a4 ?4 a0 u0 a1 u1 SEARCH NIP \ a3 ?3 ROT AND IF u1 + DUP ROT - NEGATE ELSE a0 u0 THEN 2 |N ; : s1 S" ...... <INP=456> ....." S" <INP=" S" >" SUBST ; s1 TYPE REQUIRE METER ~CHESS\TASK\METER.F METER s1 456 747 414 Ok |
Автор: | Alex [ Пн мар 02, 2009 19:46 ] |
Заголовок сообщения: | |
А у меня мысли в другую сторону бегут, одно смущает в локалсах - они необходимы там где есть интерфейс с многими параметрами например к win, OpenGL, где много стековых манипуляций - но они сковывают код, становится очень трудно уменьшить определение, разбить его на несколько частей. |
Автор: | вопрос [ Пн мар 02, 2009 20:02 ] |
Заголовок сообщения: | |
Цитата: А у меня мысли в другую сторону бегут, одно смущает в локалсах - бесконечно разбивать невозможно, в конце концов количество определений начинает смущать больше, чем их длина
они необходимы там где есть интерфейс с многими параметрами например к win, OpenGL, где много стековых манипуляций - но они сковывают код, становится очень трудно уменьшить определение, разбить его на несколько частей. |
Автор: | chess [ Пн мар 02, 2009 21:38 ] |
Заголовок сообщения: | |
Alex писал(а): А у меня мысли в другую сторону бегут, одно смущает в локалсах -
они необходимы там где есть интерфейс с многими параметрами например к win, OpenGL, где много стековых манипуляций - но они сковывают код, становится очень трудно уменьшить определение, разбить его на несколько частей. Ну тогда можно сделать много стеков в куче и туда (как на стек возвратов) что надо забрасывать и снимать или копировать. потом память под стеки освободить. Код: ( >s1 >s2 2>s1 2>s2 s1> s2> s1@ 2s1@ и т.д.)
|
Автор: | chess [ Вт мар 03, 2009 12:52 ] |
Заголовок сообщения: | |
Все-таки захотелось почуствовать как работать со стеками если их больше 2-х(4 шт) Код: : STACK-CREATE ( n -- ) CREATE HERE , CELLS ALLOT ; Выводы
: >SL CELL OVER +! @ ! ; : SL@ @ @ ; : SL-DROP DUP DUP @ = INVERT IF CELL NEGATE SWAP +! THEN ; 32 STACK-CREATE SL1 : >L1 SL1 >SL ; : 2>L1 SWAP >L1 >L1 ; : L1@ SL1 SL@ ; : L1-DROP SL1 SL-DROP ; : L1> L1@ L1-DROP ; : 2L1> L1> L1> SWAP ; 32 STACK-CREATE SL2 : >L2 SL2 >SL ; : 2>L2 SWAP >L2 >L2 ; : L2@ SL2 SL@ ; : L2-DROP SL2 SL-DROP ; : L2> L2@ L2-DROP ; : 2L2> L2> L2> SWAP ; : SUBST \ a0 u0 a1 u1 a2 u2 -- a3 u3 | S" " 2>L1 2>R 2DUP 2R@ SEARCH NIP 2>L2 2L1> SEARCH NIP L2> AND IF >L1 L2> 2R> NIP + DUP L1> - NEGATE ELSE S" " THEN ; : s1 S" ..... <INP=456>....." S" <INP=" S" >" SUBST ; s1 TYPE REQUIRE METER ~CHESS/TASK/METER.F METER s1 456 1359 477 Ok 1. Вариант с локалсами проще. 2. Латентность здесь большая(1359) из-за переписывания кэша (стеки SL1, SL2 в памяти лежат рядом с кодом SUBST, в СПФ стек параметров и стек возвратов удалены от кода на величину больше размера кэша поэтому на латентность не влияют). Стеки для уменьшения латентности нужно делать в куче. Ps. На самом деле эта задача для меня и без локалсов и без доп. стеков решается - просто для оценки простоты разных решений она подходит. |
Автор: | chess [ Вт мар 03, 2009 18:35 ] |
Заголовок сообщения: | |
Еще забыл про вариант решения с использованием стексов. Код: REQUIRE T@ ~CHESS\LIB\STACKSY.F \ 1 2 3 4 : SUBST \ a0 u0 a1 u1 a2 u2 -- \ 1 2 3 4 5 2>R 4\4123412 2R> SEARCH NIP 2>R SEARCH NIP 2R> \ u1 a3 f3 a4 f4 5\1241235 AND IF + - >R + R> ELSE 5\ S" " THEN ; : s1 S" ..... <INP=456>....." S" <INP=" S" >" SUBST ; s1 TYPE REQUIRE METER ~CHESS/TASK/METER.F METER s1 456 477 378 (латентность получилась самая низкая по сравнению с обычным способом и локалсами) Ok Если бы стексы работали с 7 параметрами(у меня максимум с 5-ю), то было бы покороче: Код: \ 1 2 3 4 5 6 7
: SUBST \ a0 u0 a1 u1 a2 u2 6\12341256 SEARCH \ a0 u0 a1 u1 a4 u4 f4 7\4571234 SEARCH \ u1 a4 f4 a3 u3 f3 6\1424136 AND IF + - >R + R> ELSE 5\ S" " THEN ; Стексы можно рассматривать как эмуляцию длинных однотактных команд управления аппаратным стеком(стековые манипуляторы). Смысл использования таких команд в том, что они так копируют-переставляют имеющиеся параметры в стеке, что после этого возможны длинные последовательности команд арифметики и логики над двумя верхними регистрами стека. Если в процессоре будет например два АЛУ, которые работают с определенными парами регистров, то с помощью стексов можно программировать параллельные вычисления. А так программировать чуть проще и "плотнее" чем обычно и труднее чем с локалсами. В целом это ускоряет вычислительный процесс. PS. В принципе можно использовать локалсы и стексы совместно. |
Автор: | Alex [ Вт мар 03, 2009 19:01 ] |
Заголовок сообщения: | |
Безусловно победителем является chess, спасибо, целая галерея разных решений !!! |
Автор: | VoidVolker [ Вт мар 03, 2009 20:18 ] |
Заголовок сообщения: | |
chess писал(а): Если бы стексы работали с 7 параметрами(у меня максимум с 5-ю), то было бы покороче:
Может быть это хороший повод для их расширения? |
Страница 2 из 2 | Часовой пояс: UTC + 3 часа [ Летнее время ] |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |