17/10/09 8:47
lorenzo
Ragazzi, da due giorni sto impazzendo su un pezzo di codice e non capisco cosa non va...allora si tratta di una classe incaricata di trasformare una stringa del tipo "3+2*4" nel suo reale valore calcolato(11 quindi)
ecco il codice:
è ancora un inizio e non è completo ma la parte che non funziona è la gestione dei numeri(vedi commento).
Allora, l'algoritmo termina correttamente e nella variabile puntatore "n" che poi inserisco nello stack ci trovo il valore corretto. Il problema è che quando faccio la Peek(o la Pop, è uguale) per ritornare il valore, mi trovo come risultato 2.4234364736e-34 cioè un numero a caso.
Perché questo???
ps: non è Delphi ma lazarus, comunque è lo stesso
ecco il codice:
unit Unit5; {$mode objfpc}{$H+} interface uses Classes, SysUtils, contnrs, Math, Dialogs; type PInt = ^Integer; { RPNCreator } RPNCreator = class private operatori: TStack; operandi: TStack; value: String; function IsOperator(c: Char): Boolean; function Precedence(n1, n2: Char): Integer; procedure ReduceOperator; function InfixToPostfix: Double; public constructor Create(v: String); function Calculate: Double; end; implementation { RPNCreator } constructor RPNCreator.Create(v: String); begin operatori := TStack.Create; operandi := Tstack.Create; value := v; //la stringa che contiene la funzione da calcolare end; function RPNCreator.Calculate: Double; begin Result := InfixToPostfix; end; function RPNCreator.IsOperator(c: Char): Boolean; begin case c of '+', '-', '*', '/', '^': Result := True; else Result := False; end; end; function RPNCreator.Precedence(n1, n2: Char): Integer; var a, b: Integer; begin case n1 of '(': a := 4; '^': a := 3; '*', '/': a := 2; '+', '-': a := 1; else a := 0; end; case n2 of '(': b := 4; '^': b := 3; '*', '/': b := 2; '+', '-': b := 1; else b := 0; end; Result := a - b; end; procedure RPNCreator.ReduceOperator; var opCurr: Char; a, b: Double; ris: PDouble; begin opCurr := Char(operatori.Pop^); case opCurr of '*': begin a := Double(operandi.Pop^); b := Double(operandi.Pop^); New(ris); ris^ := a * b; operandi.Push(ris); end; '/': begin a := Double(operandi.Pop^); b := Double(operandi.Pop^); New(ris); ris^ := a / b; operandi.Push(ris); end; '+': begin a := Double(operandi.Pop^); b := Double(operandi.Pop^); New(ris); ris^ := a + b; operandi.Push(ris); end; '-': begin a := Double(operandi.Pop^); b := Double(operandi.Pop^); New(ris); ris^ := a - b; operandi.Push(ris); end; '^': begin a := Double(operandi.Pop^); b := Double(operandi.Pop^); New(ris); ris^ := Power(a, b); operandi.Push(ris); end; end; end; function RPNCreator.InfixToPostfix: Double; var i, aux: Integer; c, s: Char; n: PInt; begin i := 1; value := Trim(value); while i < Length(value) do begin if value[i] = ')' then begin while Char(operatori.Peek^) <> '(' do begin ReduceOperator; end; operatori.Pop; end; if value[i] = '(' then operatori.Push(@value[i]) else if IsOperator(value[i]) then begin if Precedence(Char(operatori.Peek^), value[i]) < 0 then operatori.Push(@value[i]) else begin ReduceOperator; operatori.Push(@value[i]); end; end else //è un numero, vediamo se è a più cifre begin New(n); n^ := 0; while TryStrToInt(value[i], aux) do begin n^ := n^ * 10; n^ := n^ + aux; Inc(i); end; operandi.Push(n); end; Inc(i); end; while operatori.Count > 0 do ReduceOperator; Result := Double(operandi.Peek^); end; end.
è ancora un inizio e non è completo ma la parte che non funziona è la gestione dei numeri(vedi commento).
Allora, l'algoritmo termina correttamente e nella variabile puntatore "n" che poi inserisco nello stack ci trovo il valore corretto. Il problema è che quando faccio la Peek(o la Pop, è uguale) per ritornare il valore, mi trovo come risultato 2.4234364736e-34 cioè un numero a caso.
Perché questo???
ps: non è Delphi ma lazarus, comunque è lo stesso
aaa