Odwrotna notacja polska- ONP

Odwrotna notacja polska polega na zapisie beznawiasowej symboliki rachunku (twórca to Polak, Jan Łukasiewicz) .Taki sposób zapisywania wyrażeń pozwala obliczać wyrażenia podczas jednokrotnego przeglądania znaków zapisanego wyrażenia bez potrzeby cofania się.

Na przykład działanie: (2+2)/(3*3)

W ONP ma postać: 2 2 + 3 3 * /

Przy wykorzystaniu odwrotnej notacji polskiej przydaje się struktura danych zorganizowanych w stos. W języku C# stos deklaruje się jak poniżej

Stack stos = new Stack();

Należy pamiętać, że daną dostępną na stosie jest zawsze ta co ostania została do stosu wpisana (obowiązuje zasada: ostatnia wchodzi, pierwsza wychodzi). Przy obsłudze zmiennych typu Stack przydają się instrukcje:

Algorytm ONP

Po wykonaniu algorytmu, na stosie pozostanie jedna liczba będąca wynikiem zastosowania algorytmu odwrotnej notacji polskiej. Wystarczy ten wynik odczytać

Schemat algorytmu ONP

schemat algorytmu ONP Visual studio C#

Przykładowa aplikacja desktopowa wykorzystująca algorytm ONP

Proponowany układ formatki okna głównego

aplikacj aodwrotna notacja polska, Visual studio C#

Działanie aplikacji będzie wymagało zdefiniowania stosu

Wskazówka:


public partial class Form1 : Form
{
	Stack stos = new Stack();

Postać funkcji zamieniającej odczytany znak wyrażenia na cyfrę

Wskazówka:


bool cyfra(char z)
{
	//funkcja sprawdza czy znak jest cyfrą
	//zwróć wynik testu złożonego warunku logicznego
	//jak jest spełniony to PRAWDA, jak nie to FAŁSZ
	return z >= '0' && z <= '9';
}

Postać funkcji sprawdzającej czy biezacy znak wyrażenia jest operatorem działania matematycznego

Wskazówka:


bool dzialanie(char z)
{
	//funkcja sprawdza czy znak jest operatorem
	//działania matematcznego
	return z == '+' ||//dodawanie
		   z == '-' ||//odejmowanie
		   z == '*' ||//mnozenie
		   z == '/';//dzielenie
}

Postać funkcji czytającej liczby zapisane w wyrażeniu

Wskazówka:


float dajLiczbe(string lancuch,int id)
{
	//int j = id;
	//zamienia ciąg znaków na liczbę
	int liczba = 0;
	while(id<lancuch.Length && cyfra(lancuch[id]) && lancuch[id]!=' ')
	{
		//liczbe okresl na podstawie systemu pozycyjnego schematu Hornera
		//odczytaj cyfre z pozycji kodu ASCII
		liczba = liczba * 10 + lancuch[id] - '0';
		++id;
	}
	return liczba;
}

Powyższe funkcje wymagane są do prawidłowego działania przedstawionego kody algorytmu odwrotnej notacji polskiej. Algorytm ONP w utworzonej aplikacji wywoływany jest w zdarzeniu Click kontrolki Button

Wskazówka:


private void button1_Click(object sender, EventArgs e)
{
	string onp=textBox1.Text;
	//czysc poprzednią zawartośc stosu
	stos.Clear();
	for(int i = 0; i < onp.Length; i++)
	{
		if (cyfra(onp[i]))
		{
			float liczba = dajLiczbe(onp, i);
			//wrzuc odczytaną liczbę na stos danych
			stos.Push(liczba);
			//zwieksz krok o długośc znakow odczytanej liczby
			i+=liczba.ToString().Length;    
		}
		else
			if (dzialanie(onp[i]))
			{
				if (stos.Count < 2)
				{
					MessageBox.Show("To nie jest wyrażenie ONP",
									"Komunikat",
									MessageBoxButtons.OK,
									MessageBoxIcon.Error);
					return;
				}
				float b = (float)stos.Peek();
				stos.Pop();//usuń pobraną
				float a = (float)stos.Peek();
				stos.Pop();//usuń pobraną
				//wrzuc biezacy wynik obliczeń
				stos.Push(oblicz(a, b, onp[i]));
			}//koniec if dzialanie
		
	}
	MessageBox.Show(((float)stos.Peek()).ToString(),
					"Wynik",
					MessageBoxButtons.OK,
					MessageBoxIcon.Information);
}

Pełny kod programu:

Form1.cs:


using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace _24AlgONP
{
    public partial class Form1 : Form
    {
        Stack stos = new Stack();

        bool cyfra(char z)
        {
            //funkcja sprawdza czy znak jest cyfrą
            //zwróc wynik testu złożonego warunku logicznego
            //jak jest spełniony to PRAWDA, jak nie to FAŁSZ
            return z >= '0' && z <= '9';
        }
        bool dzialanie(char z)
        {
            //funkcja sprawdza czy znak jest operatorem
            //działania matematcznego
            return z == '+' ||//dodawanie
                   z == '-' ||//odejmowanie
                   z == '*' ||//mnozenie
                   z == '/';//dzielenie
        }
        float oblicz(float a,float b,char z)
        {
            switch (z)
            {
                case '+':return a + b;
                case '-': return a - b;
                case '*': return a * b;
                case '/': return a / b;
            }
            return 0;   
        }
        float dajLiczbe(string lancuch,int id)
        {
            //int j = id;
            //zamienia ciąg znaków na liczbę
            int liczba = 0;
            while(id<lancuch.Length && cyfra(lancuch[id]) && lancuch[id]!=' ')
            {
                //liczbe okresl na podstawie systemu pozycyjnego schematu Hornera
                //odczytaj cyfre z pozycji kodu ASCII
                liczba = liczba * 10 + lancuch[id] - '0';
                ++id;
            }
            return liczba;
        }
        
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            string onp=textBox1.Text;
            //czysc poprzednią zawartośc stosu
            stos.Clear();
            for(int i = 0; i < onp.Length; i++)
            {
                if (cyfra(onp[i]))
                {
                    float liczba = dajLiczbe(onp, i);
                    //wrzuc odczytaną liczbę na stos danych
                    stos.Push(liczba);
                    //zwieksz krok o długośc znakow odczytanej liczby
                    i+=liczba.ToString().Length;    
                }
                else
                    if (dzialanie(onp[i]))
                    {
                        if (stos.Count < 2)
                        {
                            MessageBox.Show("To nie jest wyrażenie ONP",
                                            "Komunikat",
                                            MessageBoxButtons.OK,
                                            MessageBoxIcon.Error);
                            return;
                        }
                        float b = (float)stos.Peek();
                        stos.Pop();//usuń pobraną
                        float a = (float)stos.Peek();
                        stos.Pop();//usuń pobraną
                        //wrzuc biezacy wynik obliczeń
                        stos.Push(oblicz(a, b, onp[i]));
                    }//koniec if dzialanie
                
            }
            MessageBox.Show(((float)stos.Peek()).ToString(),
                            "Wynik",
                            MessageBoxButtons.OK,
                            MessageBoxIcon.Information);
        }
    }
}
Alkomat- wirtualny test

Alkomat- darmowa aplikacja na Androida

Pobierz ze sklepu Google Play
Olinowanie stałe- kalkulator średnic

Olinowanie stałe- darmowa aplikacja na Androida

Pobierz ze sklepu Google Play
przepis na gogfry

Przepis na gofry

zobacz
przepis na bitą śmietanę

Przepis na bitą śmietanę

zobacz