Nadesłany przez Tomasz Lubiński, 26 lipca 2005 01:00
Kod przedstawiony poniżej przedstawia główną część rozwiązania problemu.Pobierz pełne rozwiązanie.
Jeżeli nie odpowiada Ci sposób formatowania kodu przez autora skorzystaj z pretty printer'a i dostosuj go automatycznie do siebie.
ONP.adb:
-- -- Odwrotna Notacja Polska -- www.algorytm.org (c) 2006 -- Tomasz Lubiński -- -- with Text_IO; use Text_IO; procedure ONP is Stack_pointer: Integer range 0..1000 := 0; Stack: array (1 .. 1000) of Character; procedure concat(dst : in out String; src : in String; ptr : in out Integer) is begin for i in src'Range loop ptr := ptr + 1; dst(ptr) := src(i); end loop; end; -- returns true if stack is empty, false otherwise function stackIsEmpty return boolean is begin return (Stack_pointer = 0); end; -- gets character from stack function stackPop return character is begin if Stack_pointer > 0 then Stack_pointer := Stack_pointer - 1; return Stack(Stack_pointer + 1); end if; return ' '; end; -- pushes character on stack procedure stackPush(c: Character) is begin Stack_pointer := Stack_pointer + 1; Stack(Stack_pointer) := c; end; -- gets all operators until bracket from stack function getFromStackUntilBracket return String is result : String(1..1000); ptr : Integer := 0; c : Character; begin if not stackIsEmpty then c := stackPop; ptr := ptr + 1; result(ptr) := ' '; while c /= '(' loop ptr := ptr + 1; result(ptr) := ' '; ptr := ptr + 1; result(ptr) := c; if stackIsEmpty then exit; end if; c := stackPop; end loop; end if; return result(1..ptr); end; -- gets all operators with priority less or equal to oeprator from stack function getFromStack(operator: Character) return String is result : String(1..1000); ptr : Integer := 0; c : Character; begin if not stackIsEmpty then c := stackPop; while (((operator = '+' or operator = '-') and c /= '(') or ((operator = '/' or operator = '*') and (c = '/' or c = '*'))) loop ptr := ptr + 1; result(ptr) := ' '; ptr := ptr + 1; result(ptr) := c; if stackIsEmpty then exit; end if; c := stackPop; end loop; stackPush(c); end if; stackPush(operator); return result(1..ptr); end; -- gets all from stack function getAllFromStack return String is result : String(1..1000); ptr : Integer := 0; c : Character; begin while not stackIsEmpty loop c := stackPop; ptr := ptr + 1; result(ptr) := ' '; ptr := ptr + 1; result(ptr) := c; end loop; return result(1..ptr); end; statement: String := "(2+4)*3"; sign : boolean := true; --indicates that - is a number sign (not operator minus) result : String (1..1000); ptr : Integer := 0; begin -- process all characters for i in statement'range loop if statement(i) = '(' then stackPush('('); sign := true; concat(result, " ", ptr); elsif statement(i) = ')' then concat(result, " " & getFromStackUntilBracket, ptr); sign := false; elsif (statement(i) = '+' or statement(i) = '-' or statement(i) = '*' or statement(i) = '/') and (sign = false) then concat(result, " " & getFromStack(statement(i)), ptr); sign := true; else if sign and then statement(i) = '-' then concat(result, " ", ptr); end if; concat(result, ""&statement(i), ptr); sign := false; end if; end loop; concat(result, getAllFromStack, ptr); Put_Line(statement & " ONP: " & result(1..ptr)); end;