Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Zliczanie wyrażenia

Ostatnio zmodyfikowano 2017-11-04 20:05
Autor Wiadomość
Witam321
Temat założony przez niniejszego użytkownika
Zliczanie wyrażenia
» 2017-11-03 20:34:46
Mam program , który tworzy drzewko wyrażeń , moje pytanie brzmi w jaki sposób mógłbym zrobić tak , aby wyrażenie wpisywane na początku zostawało policzone? Czyli żeby wszystko było tak jak jest , ale jeszcze pojawiał by się wynik wyrażenia.

Wstawiam kod:

C/C++
#include <iostream>
#include <string>

using namespace std;


struct BTNode
{
    BTNode * left, * right;
    char data;
};

const int S_MAX = 100;



string cr, cl, cp;


int p( char c )
{
    switch( c )
    {
    case '+':;
    case '-': return 1;
    case '*':;
    case '/': return 2;
    case '^': return 3;
    }
    return 0;
}


string ONP( string e )
{
    char S[ S_MAX ];
    int sp;
    string t;
    unsigned int i;
   
    sp = 0;
    t = "";
   
    for( i = 0; i < e.length(); i++ )
    switch( e[ i ] )
    {
    case ' ': break;
    case '(': {
            S[ sp++ ] = '(';
            break;
        }
    case ')': {
            while( S[ sp - 1 ] != '(' )
            {
                t += S[ --sp ];
                cout << S[ sp ] << " ";
            }
            sp--;
            break;
        }
    case '+':;
    case '-':;
    case '*':;
    case '/':;
    case '^': {
            while( sp )
            {
                if(( p( e[ i ] ) == 3 ) ||( p( e[ i ] ) > p( S[ sp - 1 ] ) ) ) break;
               
                t += S[ --sp ];
                cout << S[ sp ] << " ";
            }
            S[ sp++ ] = e[ i ];
            break;
        }
        default: {
            t += e[ i ];
            cout << e[ i ] << " ";
            break;
        }
    }
   
    while( sp )
    {
        t += S[ --sp ];
        cout << S[ sp ] << " ";
    }
   
    cout << endl << endl;
    return t;
}


BTNode * etree( string e )
{
    BTNode * S[ S_MAX ];
    int sp;
    BTNode * v;
    unsigned int i;
   
    sp = 0;
   
    for( i = 0; i < e.length(); i++ )
    {
        v = new BTNode;
       
        v->data = e[ i ];
       
        switch( e[ i ] )
        {
        case '+':;
        case '-':;
        case '*':;
        case '/':;
        case '^': {
                v->right = S[ --sp ];
                v->left = S[ --sp ];
                break;
            }
            default: {
                v->left = v->right = NULL;
                break;
            }
        }
        S[ sp++ ] = v;
    }
   
    return S[ sp - 1 ];
}


void DFSRelease( BTNode * v )
{
    if( v )
    {
        DFSRelease( v->left );
        DFSRelease( v->right );
        delete v;
    }
}

void printBT( string sp, string sn, BTNode * v )
{
    string s;
   
    if( v )
    {
        s = sp;
        if( sn == cr ) s[ s.length() - 2 ] = ' ';
       
        printBT( s + cp, cr, v->right );
       
        s = s.substr( 0, sp.length() - 2 );
        cout << s << sn << v->data << endl;
       
        s = sp;
        if( sn == cl ) s[ s.length() - 2 ] = ' ';
       
        printBT( s + cp, cl, v->left );
    }
}



int main()
{
   
    cout << "Prosze wpisac wyrazenie arytmetyczne:" << endl;
   
    string e;
    BTNode * root;
   
   
   
    cr = cl = cp = "  ";
    cr[ 0 ] = 218; cr[ 1 ] = 196;
    cl[ 0 ] = 192; cl[ 1 ] = 196;
    cp[ 0 ] = 179;
   
    getline( cin, e );
   
    cout << endl;
   
    root = etree( ONP( e ) );
   
    printBT( "", "", root );
   
    DFSRelease( root );
   
    return 0;
}
P-166435
Kinexity
» 2017-11-03 20:37:12
Kod jest całkowicie nieczytelny - te jedno- i dwuliterowe nazwy nie mówią nic.
P-166436
Witam321
Temat założony przez niniejszego użytkownika
Przepraszam za takie niedociągnięcie
» 2017-11-03 21:56:45
C/C++
#include <iostream>
#include <string>

using namespace std;

// Typ węzłów drzewa

struct BTNode
{
    BTNode * left, * right;
    char data;
};

const int S_MAX = 100; // rozmiar dla stosów

// Zmienne globalne
//-----------------

string cr, cl, cp; // łańcuchy do znaków ramek

// Zwraca priorytet operatora
//---------------------------
int p( char c )
{
    switch( c )
    {
    case '+':;
    case '-': return 1;
    case '*':;
    case '/': return 2;
    case '^': return 3;
    }
    return 0;
}

string ONP( string e )
{
    char S[ S_MAX ]; // Stos operatorów
    int sp; // Wskaźnik stosu
    string t; // Wynik
    unsigned int i;
   
    sp = 0; // Inicjacja stosu
    t = ""; // Zerowanie wyniku
   
    for( i = 0; i < e.length(); i++ )
    switch( e[ i ] ) // Analizujemy znak
    {
    case ' ': break; // Ignorowanie spacji
    case '(': { // Nawias otwierający zawsze na stos
            S[ sp++ ] = '(';
            break;
        }
    case ')': { // Nawias zamykający
            while( S[ sp - 1 ] != '(' )
            { // Ze stosu przesyłamy na wyjście
                t += S[ --sp ]; // wszystkie operatory aż do nawiasu otwartego
                cout << S[ sp ] << " "; // Echo na ekran
            }
            sp--; // Usuwanie nawiasu otwierajacego ze stosu
            break;
        }
    case '+':; // Operator
    case '-':;
    case '*':;
    case '/':;
    case '^': {
            while( sp )
            {
                if(( p( e[ i ] ) == 3 ) ||( p( e[ i ] ) > p( S[ sp - 1 ] ) ) ) break;
               
               
                // Na wyjście przesyłamy ze stosu wszystkie operatory o wyższych priorytetach
                t += S[ --sp ];
                cout << S[ sp ] << " "; // Echo na ekran
            }
           
           
           
            S[ sp++ ] = e[ i ]; // Operator umieszczamy na stosie
            break;
        }
        default: {
            t += e[ i ]; // Znak przesyłamy na wyjście
            cout << e[ i ] << " "; // Echo na ekran
            break;
        }
    }
   
    while( sp ) // Jeśli stos coś zawiera, to na wyjście przesyłamy całą zawartość stosu
    {
        t += S[ --sp ];
        cout << S[ sp ] << " "; // Echo na ekran
    }
   
    cout << endl << endl;
    return t;
}

// Funkcja zwraca adres korzenia drzewa wyrażeń, które zostaje utworzone na podstawie wyrażenia e


BTNode * etree( string e )
{
    BTNode * S[ S_MAX ]; // Stos
    int sp; // Wskaźnik stosu
    BTNode * v; // Adres węzła
    unsigned int i; // Indeks
   
    sp = 0; // Zerowanie stosu
   
    for( i = 0; i < e.length(); i++ ) // Przetwarzanie wyrażenia ONP
    {
        v = new BTNode; // Tworzenie nowego węzłu
       
        v->data = e[ i ]; // Umieszczamy w nim element wyrażenia
       
        switch( e[ i ] )
        {
        case '+':;
        case '-':;
        case '*':;
        case '/':;
        case '^': { // Operator
                v->right = S[ --sp ]; // Pobieramy ze stosu węzły i czynimy je synami węzła
                v->left = S[ --sp ];
                break;
            }
            default: { // Argument
                v->left = v->right = NULL; // Liść, nie ma synów
                break;
            }
        }
        S[ sp++ ] = v; // Węzeł umieszczamy na stosie
    }
   
    return S[ sp - 1 ]; // Zwracamy adres korzenia
}

// Procedura DFS:postorder usuwająca drzewo


void DFSRelease( BTNode * v )
{
    if( v )
    {
        DFSRelease( v->left ); // usuwamy lewe poddrzewo
        DFSRelease( v->right ); // usuwamy prawe poddrzewo
        delete v; // usuwamy sam węzeł
    }
}

// Procedura wypisuje drzewo


void printBT( string sp, string sn, BTNode * v )
{
    string s;
   
    if( v )
    {
        s = sp;
        if( sn == cr ) s[ s.length() - 2 ] = ' ';
       
        printBT( s + cp, cr, v->right );
       
        s = s.substr( 0, sp.length() - 2 );
        cout << s << sn << v->data << endl;
       
        s = sp;
        if( sn == cl ) s[ s.length() - 2 ] = ' ';
       
        printBT( s + cp, cl, v->left );
    }
}



int main()
{
   
    cout << "Prosze wpisac wyrazenie arytmetyczne:" << endl;
   
   
    string e; // Wyrażenie
    BTNode * root; // Korzeń drzewa
   
   
   
    cr = cl = cp = "  ";
    cr[ 0 ] = 218; cr[ 1 ] = 196;
    cl[ 0 ] = 192; cl[ 1 ] = 196;
    cp[ 0 ] = 179;
   
    getline( cin, e ); // Czytamy wyrażenie
   
    cout << endl;
   
    root = etree( ONP( e ) ); // Tworzymy drzewo wyrażeń
   
    printBT( "", "", root ); // Wyświetlamy drzewo
   
    DFSRelease( root ); // Usuwamy drzewo z pamięci
   
    return 0;
}
P-166443
pekfos
» 2017-11-03 22:39:02
Wyrażenie nie jest poprawnie konwertowane. Wpisz 12+3.
P-166446
Witam321
Temat założony przez niniejszego użytkownika
» 2017-11-04 12:52:06
Faktycznie , nie działa to tak jak powinno... Ma może ktoś pomysł jak to skorygować?
P-166453
michal11
» 2017-11-04 15:06:06
Odwrotna Notacja Polska.
P-166460
pekfos
» 2017-11-04 15:10:12
Nie trzymaj danych w jednym char.

Odwrotna Notacja Polska.
I co z nią? Poza tym, że jest już zaimplementowana u niego w kodzie?
P-166461
michal11
» 2017-11-04 20:05:02
Powinien ją zastosować do poprawnego obliczania wartości wyrażenia matematycznego. Nie napisał w pierwszym poście, że już to ma wiec założyłem, że próbuje napisać taki parser "po swojemu", szczególnie widząc taki kod
C/C++
case '^': {
    while( sp )
    {
        if(( p( e[ i ] ) == 3 ) ||( p( e[ i ] ) > p( S[ sp - 1 ] ) ) ) break;
       
nie chciało mi go czytać i szczegółowo analizować.

Ponieważ algorytm nie jest przesadnie skomplikowany to polecam dokładnie prześledzić swój kod, być może skorzystać z debuggera, szczególnie, że dostałeś konkretny przykład dla którego twój kod nie działa.
P-166474
« 1 »
  Strona 1 z 1