Szeretnék felolvasni egy kifejezést, és lengyel-formára bontani, de a ?: operátornál megakadtam.
Az algoritmus, amit a lengyel-formához ajánlgatnak, mindenhol szavanként, tokenenként olvassa sorban a kifejezést, de a ?: operátor önmaga egy operátor, míg felolvasás közben két külön token, ráadásul további operátorok is kerülhetnek közéjük.
Tudtok segíteni abban, mi a korrekt lengyel-formára alakítási algoritmusa egy stringnek, ha van benne ?: operátor is?
- 539 megtekintés
Hozzászólások
Igy hirtelen arra gondolnek hogy a ? es : operatorokat parba allitod, es ugy kezeled mint a ( ... ) part az algoritmus szempontjabol, azonban a : eseten a megfelelo prioritassal felveszel egy operatort es akkor veszed ki a stack-bol es teszed be az PSN sorozatba, amikor mint egy sima operator eljon az ideje. Hogy mi a prioritasa az jo kerdes, de szerintem ez az egyik legalacsonyabb prioritasu.
Es akkor mar csak arra kell figyelni hogy az egymasba agyazott ?:-k jol menjenek. De ez ugyanaz a problemakor mint amikor az a kerdes hogy az a+b+c-bol [a][b][+][c][+] -t vagy [a][b][c][+][+] format csinalsz.
- A hozzászóláshoz be kell jelentkezni
Nyilván meg lehet csinálni, csak nem lesz jó, ugyanis a rövidzár kiértékelést így nem lehet megcsinálni. Mondjuk van egy ilyen példa:
x==0 ? 100 : 100/x
ha ezt lefordítod arra, hogy:
x ( x )
0 ( x 0 )
== ( f )
100 ( f 100 )
100 ( f 100 100 )
x ( f 100 100 x )
/ ( f 100 100/x )
?: ( 100 vagy 100/x)
Akkor máris nem kerülted el a nullával osztás problémáját.
Szerk: egy kicsit átszerveztem; valamint hozzátenném, hogy a zárójelek között a verem pillanatnyi állapota látszik FORTH-stílusban; az 'f' egy logikai érték (flag), miszerint nulla volt-e az 'x' értéke
- A hozzászóláshoz be kell jelentkezni
Nem így lenne ez helyes?
x ( x )
0 ( x 0 )
== ( f )
100 ( f ( 100 ) )
100 ( f ( 100 ) ( 100 ) )
x ( f ( 100 ) ( 100 x ) )
/ ( f ( 100 ) ( 100 x / ) )
?: ( 100 vagy 100/x )
Ha a Postscript jelölésrendszerét nézem:
x 0 eq { 100 } { 100 x div } ifelse exec
Tehát nem szabad kiértékelni a kifejezést, amíg nem derül ki, melyiket kell!
- A hozzászóláshoz be kell jelentkezni
Itt nincsenek ilyen beágyazott stack-ek meg késleltetett végrehajtású részek. Például a Forth-ban a user beírja, hogy
x 0 ==
IF
100 x /
ELSE
100
THEN
Az belsőleg ilyemi lesz:
x
0
==
0BRANCH addr1
100
x
/
BRANCH addr2
addr1: 100
addr2:
- A hozzászóláshoz be kell jelentkezni
Nyilván meg lehet csinálni, csak nem lesz jó, ugyanis a rövidzár kiértékelést így nem lehet megcsinálni.
Erre is teljesen jo a PSN (reverse/suffix) jeloles:
[x] [0] [==] [100] [100] [x] [/] [?:].
Kiertekelesnel meg ugy implementalod a verem-strukturat hogy a verem egyes elemei nemcsak operandusok es operatorok lehetnek hanem onallo PSN sorozatok is (hierarchikus rendszer). Es az egyes operandusoknak megfelelo PSN sorozatokat viszont csak akkor ertekeled ki ha szukseg is van ra. Sima ügy, sok ilyet/hasonlot csinaltam mar :) Ebben a peldaban ez igy fog kinezni:
[[x] [0] [==]] [100] [[100] [x] [/]] [?:]
A [?:] elott 3 sorozat van mint operandus. Az elsot mindenkepp ki kell ertekelnie. Es annak az eredmenyetol fuggen ertekeli ki a masodikat vagy harmadikat. Amelyiket nem kell kiertekelnie azt eldobja. Ugyanez a logika jo a && meg || esetekre is.
- A hozzászóláshoz be kell jelentkezni
Ez igy valoban mukodhet, de van egy nagy hibaja: minden esetben kiertekeli mindket tagot. Azt is, amit utana eldobsz, pedig igazabol tudod, melyiket kell kiertekelni.
- A hozzászóláshoz be kell jelentkezni
de miert kene kiertekelnie? ld. fentebb.
- A hozzászóláshoz be kell jelentkezni
Fogalamam sem volt mi a lengyel forma, de elolvastam egy rövid bevezetőt az ELTE honalpján
https://people.inf.elte.hu/veanna/alg1/segedanyagok/LengyelForma/index…
Szerintem ez aritmetikai/logikai operátorokra vonatkozik, a "?:" az egyik sem (szerintem), ez syntactic sugar hogy ne kelljen if-else blockot írni.
Pythonban ez nem is létezik, ott így néz ki
x = érték1 if feltétel else érték2
Szóval ez szerintem egy kakukk tojás és belül a fordító egy if-else utasításra átfordítja.
// Hocus Pocus, grab the focus
winSetFocus(...)
http://c2.com/cgi/wiki?FunnyThingsSeenInSourceCodeAndDocumentation
- A hozzászóláshoz be kell jelentkezni
A C nyelvben van ilyen operátor, és valóban operátornak tűnik. Van asszociativitása és precedenciája is. Az "a?b:c" lengyel-formára hozott alakja valahogy így néz ki "a b c ?:".
Amúgy sem emlékszem olyan megkötésre, hogy a lengyel-formára hozás csak maximum két paraméteres operátorokra működne.
- A hozzászóláshoz be kell jelentkezni
Az oké hogy operátornak tituláljuk. Gondolom mivel leírható más operátorokkal egy sorba ezért operátornak nevezik és kapott precedenciát, de ez inkább vezérlési szerkezetre hasonlít.
A matek tudásom már majdnem teljesen elkopott de nekem nem rémlik elágazás operátor, ez meg éppen az.
// Hocus Pocus, grab the focus
winSetFocus(...)
http://c2.com/cgi/wiki?FunnyThingsSeenInSourceCodeAndDocumentation
- A hozzászóláshoz be kell jelentkezni
Én ismertem, csak reverse Polish notation (RPN) néven. Sose szerettem, nem bírom megszokni. Se számológépeknél, se dc-ben, sem nyelveknél (PS). Valahogy nagyon nyakatekertnek tűnik, állandóan tudatosítani kell, hogy mi van a stack-ben, melyik operátor pontosan mire fog vonatkozni. Nagyon kontraintuitív. Más felől viszont régen pont azért volt népszerű, mert könnyű interpretálni, kisebb hardver és erőforrás kell hozzá. Ugyanez igaz a funkcionális programozásra, azt se bírom rendesen megérteni, mert ott ugyebár a hagyományos imperatív, strukturális módszerek nem működnek, nem nyúlhat az ember a változókhoz, nem úgy néznek ki a loopok, stb..
Amit én a topiknyitóban nem értek, hogy pontosan milyen kifejezésről van szó, milyen nyelven, és mi célból akarja a kolléga „felolvasni”, RPN-re alakítani.
“Windows 95/98: 32 bit extension and a graphical shell for a 16 bit patch to an 8 bit operating system originally coded for a 4 bit microprocessor, written by a 2 bit company that can't stand 1 bit of competition.”
- A hozzászóláshoz be kell jelentkezni
Szerintem a ?: operátor kiértékeléséhez nem lesz elegendő a pushdown automata, ezért aztán hiába szervezed stackbe a kifejezés parzolt alakják, értelmezni nem fogod tudni, ahhoz Turing-gép kell.
Edit: bocs, valszeg hülyeséget mondtam. Nested stack automata is jó lesz neked, az már elegendő egy ilyen nyelv kiértékeléséhez.
- A hozzászóláshoz be kell jelentkezni
Érdemes lenne nem utánozni a PHP hibáját: ha van egy ilyen kifejezésünk:
a==1 ? b : a==2 ? c : d
Az PHP-ben ezt jelenti:
(a==1 ? b : a==2) ? c : d
A többi programozási nyelven:
a==1 ? b : (a==2 ? c : d)
- A hozzászóláshoz be kell jelentkezni
Szerintem ez nem hiba, mert emberi intuíció mentén a PHP megoldásával értek egyet. Plusz ez pontosan definiálható a nyelv specifikációjában, hogy mi a kiértékelési sorrend. Persze az még jobb, ha mindent agyonzárójelezünk, a gépnek felesleges, de az emberi tényező miatt jó. Én pont emiatt nem szeretem a x y z * + formát, mert aki nem RPN-mágus, rohadtul belezavarodik, míg a ((x y *) z +) sokkal világosabbá teszi, még a gyp-seknek is. Ez kétség kívül hasznos a Lisp-ben, hogy a zárójelezés mindig világosan mutatja, hogy melyik függvényhívás milyen paraméterekre fog vonatkozni. Persze egyben idegesítő is követni, hogy minden zárójel le legyen zárva, könnyű kifelejteni egyet-egyet.
“Windows 95/98: 32 bit extension and a graphical shell for a 16 bit patch to an 8 bit operating system originally coded for a 4 bit microprocessor, written by a 2 bit company that can't stand 1 bit of competition.”
- A hozzászóláshoz be kell jelentkezni
Talán jobb példa ez:
a==1 ? "Egy" :
a==2 ? "Ketto" :
a==3 ? "Harom" :
"Egyeb";
Ez minden nyelven azt csinálja, amit gondolok, hogy csinál, kivéve PHP-ben.
- A hozzászóláshoz be kell jelentkezni
Az első példád is ugyanilyen jó volt. Ez igazából preferencia kérdése. Nekem a PHP megoldása a logikusabb, neked a többié. Oda-vissza lehet érvelni. Szerintem az emberek a balról jobbra értelmezést szokták meg, pl. olvasásnál, számolásnál is, ezért szerintem intuitívabb a PHP-s módszer, ha a többiek akarják, tarthatunk róla szavazást. A másik fajta rendszer mögött meg az lehet a logika, hogy egymásba ágyazott if then else szerkezeteknél a legmélyebbre beágyazott, legbelül, legvégül meghívott szerkezetnek teljes, tovább nem bontható if then else-nek kell lennie, és ezt kiértékelve ágyazza be a többi kifejezésbe, de ez szerintem elég gépies logika, viszont ilyen oldalról meg az RPN mentalitásába jobban beleillik, ha tényleg az RPN a cél, igaz akkor meg a if then else ? : formáról vitatkoznánk, és nem az if ? then : else-ről.
“Windows 95/98: 32 bit extension and a graphical shell for a 16 bit patch to an 8 bit operating system originally coded for a 4 bit microprocessor, written by a 2 bit company that can't stand 1 bit of competition.”
- A hozzászóláshoz be kell jelentkezni