Nejste přihlášen/a.
Dobrý den,
Pokouším se v C# napsat Shunting-yard algoritmus (algoritmus pro převod matematického výrazu z infixového do postfixového zápisu).
Pro vysvětlení:
a
Zatím vypadá následovně. Pro jednoduchost jsem zatím vynechal práci s funkcemi (odmocniny, logaritmy, goniometrie...), vícecifernými či desetinnými čísly a zachytávání chyb. Zahrnul jsem jen základní matematické operace (plus, mínus, krát, děleno, mocnina) a práci se závorkami:
==========
string vstup = "";
string vystup = "";
string cisla = "0123456789"; // řetězec pro identifikaci čísel
string operatory = "+-*/^"; // řetězec pro identifikaci operátorů
Dictionary priorita = new Dictionary(); // slovník pro přiřazení priority operátorů
priorita.Add("+", 1);
priorita.Add("-", 1);
priorita.Add("×", 2);
priorita.Add("÷", 2);
priorita.Add("^", 3);
Dictionary asociativita = new Dictionary(); // slovník pro přiřazení asociativity operátorů
asociativita.Add("+", 'l');
asociativita.Add("-", 'l');
asociativita.Add("×", 'l');
asociativita.Add("÷", 'l');
asociativita.Add("^", 'r');
Stack zasobnik = new Stack(); // zavedení zásobníku
int i = 0;
int delka = vstup.Length;
// následuje samotný algoritmus:
// Dokud jsou zde tokeny ke čtení:
for (i = 0; i < delka; i++)
{
// Přečti token.
string token = vstup.Substring(i, 1);
// Pokud je token číslo, přidej ho do výstupní fronty.
if (cisla.Contains(token))
{
vystup += token;
}
// Pokud je token operátor (dále jen o1), tak:
else if (operatory.Contains(token))
{
string o1 = token;
// dokud bude na vrcholu zásobníku operátor (s výjimkou závorek), o2, tak:
while (zasobnik.Count()!= 0 && operatory.Contains(zasobnik.Peek())
{
string o2 = zasobnik.Pop();
// pokud je o1 asociativní zleva a jeho priorita je menší nebo stejná (≤ jako priorita o2, nebo
// o1 je asociativní z prava a jeho priorita je nižší (
Tak jsem to zrovna vyřešil...
Problém byl zde:
==========
// Pokud je token operátor (dále jen o1), tak:
else if (operatory.Contains(token))
{
string o1 = token;
// dokud bude na vrcholu zásobníku operátor (s výjimkou závorek), o2, tak:
while (zasobnik.Count()!= 0 && operatory.Contains(zasobnik.Peek())
{
string o2 = zasobnik.Pop();
// pokud je o1 asociativní zleva a jeho priorita je menší nebo stejná (&le jako priorita o2, nebo
// o1 je asociativní z prava a jeho priorita je nižší (< než priorita operátoru o2,
if ((asociativita[o1] == 'l' && priorita[o1]
Takhle to ale nebude fungovat správně, ne? Když bude na zásobníku víc operátorů v řadě, popne se jen první z nich a místo popnutí i zbytku operátorů začnete číst další vstup.
Neneseme odpovědnost za správnost informací a za škodu vzniklou jejich využitím. Jednotlivé odpovědi vyjadřují názory jejich autorů a nemusí se shodovat s názorem provozovatele poradny Poradte.cz.
Používáním poradny vyjadřujete souhlas s personifikovanou reklamou, která pomáhá financovat tento server, děkujeme.