Tło:Modelowanie manewrowaniem-Yard Algorytm
Próbuję zaimplementować wariant Shunting-Yard Algorithm, ale zamiast wyprowadzania wyrażenia w notacji RPN, chciałbym go zaktualizować się jako tokeny są wypychane w tak wyniki mogą być wyświetlane w czasie rzeczywistym (tak jakbyś naciskał przyciski na kalkulatorze i musiał aktualizować wyświetlacz po każdym przycisku).
Oto klasa Manewrowanie stoczni ...
public class ShuntingYard
{
private Stack<double> _operands;
private Stack<Operation> _operations;
public ShuntingYard()
{
this._operands = new Stack<double>();
this._operations = new Stack<double>();
}
}
I klasa Operation
byłoby coś ...
public abstract class Operation
{
public abstract void Evaluate(Stack<double> operands, Stack<Operation> operations);
}
Funkcja Evaluate()
aktualizuje Odpowiednio stosy, a " bieżąca wartość "to _operands.Peek()
Oto niektóre z" Operacji "jakie dotychczas miałem:
public class NullaryOperation : Operation { }
E.g. Pi, e, itp
Wystarczy popycha stała na _operands
public class UnaryOperation : Operation { }
Np SquareRoot, sinus, cosinus, itp
Pops jeden numer off _operands
, ocenia, i popycha doprowadzić do _operands
public class BinaryOperation : Operation { }
Np +, -, *, /, itp
Kontrole pierwszeństwa, ocenia, jeśli to konieczne, popycha doprowadzić do _operands
Oto problem:
muszę zdolność do pchania open nawiasów (
i zamkniętej nawiasy )
na stos _operations
jako część algorytmu. Co więcej, kiedy dodaję nawias zamknięty, muszę trzymać popping operandy/operacje, dopóki nie napotkam otwartego nawiasu.
chcę uniknąć kontroli tak (rodzaje kontroli Object):
while (operations.Peek().GetType() != typeof(OpenParen)) { ... }
chcę uniknąć dodawania metody takie jak to w Operation
:
public abstract bool IsOpenParen();
mogłem zrobić coś takiego ...
public abstract class Operation
{
public enum OperationType { Nullary, Unary, Binary, OpenParen, CloseParen };
public abstract OperationType GetOperationType() { };
public abstract void Evaluate(Stack<double> operands, Stack<Operation> operations);
}
Jednak wymaganie, aby wszystkie podtypy określały ich typ jako wyliczenie, wydaje się złym projektem.
Jak mam to modelować w taki sposób, aby móc śledzić i obsługiwać nawiasy, gdy są wciskane?
Na marginesie: myślenie o nawiasach jako "Operacjach" nie ma dla mnie większego sensu. Jednak algorytm na Wikipedii traktuje je w ten sposób i nie mogę wymyślić żadnego innego sposobu na śledzenie ich pozycji względem innych "prawdziwych" operacji.
Dziękuję.
Każdy powód, dla którego nie chcesz tworzyć parensów do zadań specjalnych w swoim projekcie, gdy wyraźnie potrzebujesz specjalnej obsługi ich w swojej aplikacji? Mam na myśli, jestem pewien, że mógłbyś * wymyślić jakąś abstrakcyjną koncepcję, więc nie jest to już specjalny przypadek, ale brzmi to jak nadmierne prześwietlenie, chyba że wiesz, że jest więcej konstruktów, którymi musisz się posługiwać w podobny sposób. – millimoose
Nawiasy są niepotrzebne w notacji polskiej, zarówno do przodu, jak i do tyłu; są one wymagane tylko w notacji typu infix. –
@PieterGeerkens Algorytm Shunting-Yard analizuje wyrażenie notacji infiksowej. RPN jest tylko jednym z możliwych wyjść. – millimoose