Forth http://fforum.winglion.ru/ |
|
выдать подстроку из исходной строки http://fforum.winglion.ru/viewtopic.php?f=19&t=1981 |
Страница 1 из 2 |
Автор: | Alex [ Вт фев 24, 2009 19:54 ] |
Заголовок сообщения: | выдать подстроку из исходной строки |
Есть исходная строка ( a u ) необходимо выдать подстроку, которая следует после заданной подстроки (a1 u1) и завершается перед строкой ( a2 u2). пример: исходная строка S" nhghgh<inp=456>ngnghtiro" , подстроки-ограничители S" <inp=" и S" >", следует выдать S" 456" желательно красивое и понятное рещение. |
Автор: | WingLion [ Вт фев 24, 2009 20:00 ] |
Заголовок сообщения: | |
Еще желательнее красивое и понятное условие. |
Автор: | VoidVolker [ Вт фев 24, 2009 20:24 ] |
Заголовок сообщения: | |
Код: : GET-SUBST { a0 u0 a1 u1 a2 u2 -- a3 u3 | a0 u0 } \ Получить подстроку a3 u3 из строки a0 u0, ограниченную a1 u1 и a2 u2 a0 u0 a1 u1 SEARCH IF u1 u1 NEGATE D+ 2DUP a2 u2 SEARCH IF NIP OVER - ABS NIP ELSE 2DROP 2DROP a0 u0 THEN ELSE 2DROP a0 u0 THEN ; Пример: Код: S" ненужный текст <inp=456> еще лишний текст" S" <" S" >" GET-SUBST TYPE
inp=456 Ok |
Автор: | VoidVolker [ Вт фев 24, 2009 20:56 ] |
Заголовок сообщения: | |
Второй вариант: Код: : GET-SUBST2 { a0 u0 a1 u1 a2 u2 -- a3 u3 | a0 u0 } \ Получить подстроку a3 u3 из строки a0 u0, ограниченную a1 u1 и a2 u2 или ограниченную a2 u2 и a1 u1 - т.е. порядок строк-ограничителей не важен. a0 u0 a1 u1 SEARCH IF a0 u0 a2 u2 SEARCH IF ROT - ABS >R MIN R> u1 u2 MAX DUP NEGATE D+ ELSE 2DROP 2DROP a0 u0 THEN ELSE 2DROP a0 u0 THEN ; Код: S" ненужный текст <inp=456> еще лишний текст" S" <inp=" S" >" GET-SUBST2 TYPE
456 Ок S" ненужный текст <inp=456> еще лишний текст" S" >" S" <inp=" GET-SUBST2 TYPE 456 Ок |
Автор: | chess [ Ср фев 25, 2009 08:46 ] |
Заголовок сообщения: | |
Для скорости реализация локалсов на нижнем уровне ( слово S| можно использовать в определении многократно) Код: REQUIRE IDN ~CHESS\ASSM\SP-ASSM.F USER FIX-SP : ASF> FIX-SP >CS ; IMMEDIATE : S| $ -4 B=aP ASF> @=B ; : PAR DUP ASF> B=@ ; : P1 PAR $ 0 A=@B ; : P2 PAR $ 4 A=@B ; : P3 PAR $ 8 A=@B ; : P4 PAR $ C A=@B ; : P5 PAR $ 10 A=@B ; : P6 PAR $ 14 A=@B ; : P7 PAR $ 18 A=@B ; \ и т.д. - через NOTFOUND возможно определение сразу группы слов вида Pn. : AS0> S0 >CS ; IMMEDIATE : |1 AS0> P=@ ; \ оставить один параметр : |2 RS=@P |1 $ -4 Pa @P=RS ; \ оставить два \ Получить подстроку a3 u3 из строки a0 u0, ограниченную строками a1 u1 и a2 u2 : SUBST \ a0 u0 a1 u1 a2 u2 -- a3 u3 | \ P6 P5 P4 P3 P2 P1 S| P3 P6 P5 P4 P3 SEARCH \ P7 P6 P5 P4 P6 P5 P2 P1 SEARCH \ P3 P2 P1 S| P4 P1 AND IF P6 P7 + P3 P6 - P7 - ELSE P6 P5 THEN |2 ; Код: S" .......<inp=456> ......." S" <inp=" S" >" SUBST TYPE PS. С такими локалсами возможны более прямые действия.
456 Ok |
Автор: | Гость [ Ср фев 25, 2009 10:10 ] |
Заголовок сообщения: | |
Код: S" nhghgh<inp=456>ngnghtiro" S" <inp=" SUBSTRING-AFTER S" >" SUBSTRING-BEFORE
|
Автор: | chess [ Ср фев 25, 2009 11:10 ] |
Заголовок сообщения: | |
Код: : "S" NextWord NextWord SUBST ;
S" .......<inp=456> ......." "S" <inp= > TYPE 456 Ok |
Автор: | chess [ Ср фев 25, 2009 15:15 ] |
Заголовок сообщения: | |
Сравнил быстродействие вариантов решения задачи: Код: : s1 S" .......<inp=456> ......." S" <inp=" S" >" GET-SUBST ; \ VoidVolker1
: s2 S" .......<inp=456> ......." S" <inp=" S" >" GET-SUBST2 ; \ VoidVolker2 : s3 S" .......<inp=456> ......." S" <inp=" S" >" SUBST ; \ chess REQUIRE METER ~CHESS\TASK\METER.F STARTLOG METER s1 METER s2 METER s3 621 351 \ VoidVolker1 702 396 \ VoidVolker2 639 387 \ chess Ok Несмотря на всю громоздкость стековых локалсов(смещение в стеке из памяти брать приходится), быстродействие практически одинаковое получилось. |
Автор: | Alex [ Ср фев 25, 2009 16:58 ] |
Заголовок сообщения: | |
Вот реализация через стек возвратов Код: : param ( a u a1 u1 a2 u2 -- a0 u0 ) 2>R DUP >R SEARCH IF R@ R> NEGATE D+ OVER 2R> ROT >R SEARCH IF DROP R@ - R> SWAP ELSE RDROP THEN ELSE RDROP RDROP RDROP 2DROP S" " THEN ; S" FKFKFK<inp=456>GKGKGK" S" <inp=" S" >" param TYPE |
Автор: | chess [ Ср фев 25, 2009 17:46 ] |
Заголовок сообщения: | |
Как говорил true-grue "отвратительное нагромождение стековых операторов". По мне это действительно так. Вот я применил работу с участками стека как с массивами и стало легче. Стек это идеальное место для создания локальных переменных(только без образования динамических словарей). На стеке можно легко создать локальные переменные и также легко их убрать. Очистка мусора на стеке без побочных эффектов и очень быстрая. Локальные переменные могут создаваться и убираться сколько угодно раз и при этом программист будет удерживать в поле своего внимания в нужном месте вычислительного процесса только нужное по задаче число статических параметров. Обратная польская запись очищается от стековых манипуляций и становится прозрачной. Единственно что еще нужно сделать это перейти к именованию параметров(пока они безымянны). Единственным оправданием такого письма по-старому может служить быстродействие кода, но и тут если уж надо очень быстро, то можно спуститься до ассемблера(там тоже все прозрачно). |
Автор: | chess [ Чт фев 26, 2009 18:55 ] |
Заголовок сообщения: | |
Оказалось, что приведенное мною решение все-таки частное. Я там сброс стека делал полностью, а так нельзя так как на стеке могут лежать параметры от предыдущих вычислений. Поэтому привожу правильное решение на форте: Код: USER FIX-NPAR
USER FIX-SP : P| ( n -- ) FIX-NPAR ! SP@ 4 - FIX-SP ! ; : PN ( n -- Pn ) CELLS FIX-SP @ + @ ; : |N ( P1...Pk n -- Pk-n...Pk ) N>R SP@ FIX-NPAR @ CELLS + SP! NR> DROP ; : 1| 1 P| ; : 2| 2 P| ; : 3| 3 P| ; : 4| 4 P| ; : 5| 5 P| ; : 6| 6 P| ; : 7| 7 P| ; : 8| 8 P| ; : 9| 9 P| ; : P1 1 PN ; : P2 2 PN ; : P3 3 PN ; : P4 4 PN ; : P5 5 PN ; : P6 6 PN ; : P7 7 PN ; : P8 8 PN ; : P9 9 PN ; : |1 1 |N ; : |2 2 |N ; : |3 3 |N ; : |4 4 |N ; : |5 5 |N ; : |6 6 |N ; : |7 7 |N ; : |8 8 |N ; : |9 9 |N ; : SUBST ( a0 u0 a1 u1 a2 u2 -- a3 u3 | a0 u0) 6| P6 P5 P4 P3 SEARCH P6 P5 P2 P1 SEARCH P3 P6 P5 |9 9| P7 P4 AND IF P9 P3 + DUP P6 - ABS ELSE P2 P1 THEN |2 ; : s1 S" ..... <INP=456>....." S" <INP=" S" >" SUBST ; s1 TYPE 456 Ok Появилась необходимость фиксировать количество параметров как локальных переменных(слова - 6|, 9|), чтобы появилась информация для слов типа |9, |2, которые оставляют параметры на стеке "а из какого количества параметров оставить нужное количество верхних параметров". Хотя от стековых операторов так можно избавиться, но всвязи с возможностью многократного объявления локальных переменных в одном определении необходимость перехода от безымянных локалсов к именованным усилилась. Возможное решение таблица имен с закреплением за номером имени в локусе - кода процедуры вытаскивания соответствующего параметра на стек(слова P1... Pn). |
Автор: | VoidVolker [ Чт фев 26, 2009 20:12 ] |
Заголовок сообщения: | |
chess писал(а): привожу правильное решение на форте
Тогда наверно надо протестировать и скорость? Кстати, можно еще сравнить и количество создаваемого кода разными решениями. |
Автор: | chess [ Пт фев 27, 2009 08:44 ] |
Заголовок сообщения: | |
VoidVolker писал(а): Тогда наверно надо протестировать и скорость? Кстати, можно еще сравнить и количество создаваемого кода разными решениями.
Понятно, что эмуляция "форт-процессора" (это я про вариант локалсов на форте) всегда будет медленнее(на ассме будет попрежнему как и раньше, так как принципиальных доп. затрат времени не видно). Код: : s1 S" ..... <INP=456>....." S" <INP=" S" >" SUBST ;
REQUIRE METER ~CHESS/TASK/METER.F METER s1 1071 621 Ок Количество памяти на код меня уже не интересует, даже в МК проблема памяти перестала быть острой. |
Автор: | Alex [ Пт фев 27, 2009 09:12 ] |
Заголовок сообщения: | |
chess, обратите внимание что в Вашем решении мы избавились от жонглирования на стеках, но осталась сложность с необходимостью контролировать и представлять в голове количество параметров на стеке. Вот здесь ... P3 P6 P5 |9 ... мы оставляем на стеке 9 параметров из 12, и далее перенумерорываем их 9| , наверно даже можно ввести такое слово : |9| |9 9| ; Сложность в решении по моемому уменьшилась и переползла в другие места. Я предполагал, что можно поискать решения в духе http://www.ddj.com/embedded/210600604 http://objectmix.com/forth/769600-b-registers-forth.html http://groups.google.com/group/comp.lang.forth/browse_thread/thread/8bfa810fdaa3502a/20d3f09b681dedbc?lnk=gst&q=marcel+hendrix+a%2Fb+registers#20d3f09b681dedbc где товарищи вводят "регистры" A,B,X,Y и показывают, что на некоторых задачах это может существенно упростить и запись и скорость выполнения. На эти наши локальные переменные P1,P2 ... мы тоже можем посмотреть как на "регистры" т.е. можно определить для них разные инкременты и декременты обозначив соответствующими иероглифами P1@+ , P1@- , P1!+ ( о боже куда меня понесло ! ) |
Автор: | VoidVolker [ Пт фев 27, 2009 09:20 ] |
Заголовок сообщения: | |
chess писал(а): Количество памяти на код меня уже не интересует, даже в МК проблема памяти перестала быть острой. Предложил из чистого любопытства Alex писал(а): Сложность в решении по моемому уменьшилась и переползла в другие места.
Да, я тоже так считаю. |
Страница 1 из 2 | Часовой пояс: UTC + 3 часа [ Летнее время ] |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |