Nejste přihlášen/a.

Přihlásit se do poradny

 

Nefunguje algoritmus v C# - co mám špatně?

Od: lemplar odpovědí: 3 změna:

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í:

cs.wikipedia.org/...

a

cs.wikipedia.org/...

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žší (

 

 

3 odpovědi na otázku
Řazeno dle hodnocení

 

 

lemplar

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]

dzordz*

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.

jenom takové doplnění:

Nedeklaruje se náhodou třída Dictionary tímto způsobem?

Dictionary< TYP1, TYP2> NAZEV = new Dictionary< TYP1, TYP2>();?

 

 


 

 

 

Přihlásit se k odběru odpovědí z této otázky:

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.

Copyright © 2004-2025 Poradna Poradte.cz. Všechna práva vyhrazena. Prohlášení o ochraně osobních údajů. | [tmavý motiv]