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

Kalkulator

Ostatnio zmodyfikowano 2009-07-28 20:14
Autor Wiadomość
kampar
Temat założony przez niniejszego użytkownika
Kalkulator
» 2009-07-23 14:41:14
Witam. Chciałem stworzyć kalkulator w którym wpisywałoby sie działanie z '=' na końcu i po nacisnieciu entera wyswietlil by sie wynik. Zabrałem sie do roboty i wyszlo mi takie cos:
C/C++
#include <iostream>
#include <conio.h>

using namespace std;

int main()
{
   
    int a = 1;
    int liczba[ a ];
    char znak[ a ];
   
    cout << "Napisz dzialanie" << endl;
    cin >> liczba[ 0 ];
    cin >> znak[ 0 ];
   
    for( int i = 0; i <= a; i++ )
    {
        a++;
       
        cin >> liczba[ i + 1 ];
       
        switch( znak[ i ] )
        {
        case '+':
            liczba[ i + 1 ] = liczba[ i ] + liczba[ i + 1 ];
            break;
        case '-':
            liczba[ i + 1 ] = liczba[ i ] - liczba[ i + 1 ];
            break;
        case '*':
            liczba[ i + 1 ] = liczba[ i ] * liczba[ i + 1 ];
            break;
        case '/':
            liczba[ i + 1 ] = liczba[ i ] / liczba[ i + 1 ];
            break;
           
        }
        cin >> znak[ i + 1 ];
       
        if( znak[ i + 1 ] == '=' )
        {
            cout << "Wynik to: " << liczba[ i + 1 ] << endl;
            break;
           
        }
    }
   
    getch();
    return( 0 );
}

Dopiero po napisaniu tego zobaczylem ze moj program wykonuje dzialania po kolei, czyli nie bierze pod uwage kolejnosci rozwiazywania rownania (2+3*2 dla niego rowna sie 10, a powinno byc 8). Zabrałem sie wiec do roboty od nowa i stanalem na tym:

C/C++
#include <iostream>
#include <conio.h>

using namespace std;

int main()
{
    int liczba[ 4 ];
    char znak[ 3 ];
    int wynik[ 2 ];
   
    cout << "Napisz dzialanie" << endl;
    cin >> liczba[ 0 ];
    cin >> znak[ 0 ];
    cin >> liczba[ 1 ];
    cin >> znak[ 1 ];
    cin >> liczba[ 2 ];
    cin >> znak[ 2 ];
    cin >> liczba[ 3 ];
   
    switch( znak[ 0 ] )
    {
    case '*':
        wynik[ 0 ] = liczba[ 0 ] * liczba[ 1 ];
        break;
    case '+':
        break;
    }
   
    switch( znak[ 1 ] )
    {
    case '*':
        switch( znak[ 0 ] )
        {
        case '*':
            wynik[ 0 ] = wynik[ 0 ] * liczba[ 2 ];
            break;
        case '+':
            wynik[ 0 ] = liczba[ 1 ] * liczba[ 2 ];
            break;
        }
        break;
    case '+':
        break;
    }
   
    switch( znak[ 2 ] )
    {
    case '*':
        switch( znak[ 1 ] )
        {
        case '*':
            wynik[ 0 ] = wynik[ 0 ] * liczba[ 3 ];
            break;
        case '+':
            wynik[ 1 ] = liczba[ 2 ] * liczba[ 3 ];
            break;
        }
        break;
    case '+':
        break;
    }
   
    /////////////////////////////     
   
   
    switch( znak[ 0 ] )
    {
    case '+':
        switch( znak[ 1 ] )
        {
        case '+':
            wynik[ 0 ] = liczba[ 0 ] + liczba[ 1 ];
            break;
        case '*':
            wynik[ 0 ] = wynik[ 0 ] + liczba[ 0 ];
            break;
        }
        break;
    case '*':
        break;
    }
   
    switch( znak[ 1 ] )
    {
    case '+':
        switch( znak[ 2 ] )
        {
        case '+':
            wynik[ 0 ] = wynik[ 0 ] + liczba[ 2 ];
            break;
        case '*':
            wynik[ 0 ] = wynik[ 0 ] + wynik[ 1 ];
            break;
        }
        break;
    case '*':
        break;
    }
   
    switch( znak[ 2 ] )
    {
    case '+':
        wynik[ 0 ] = wynik[ 0 ] + liczba[ 3 ];
        break;
    case '*':
        break;
    }
   
   
   
   
    cout << "Wynik to: " << wynik[ 0 ] << endl;
   
   
    getch();
    return( 0 );
}

Otoz nie moge wymyslec jak to wszystko zapetlic aby sie zgadzalo( tak jak w pierwszym programie). Jesli ktos wie jak to rozwiazac to prosze niech da jakas mala podpowiedz co mam zrobic dalej. Z góry dzieki za odpowiedz.
P-8737
pompom
» 2009-07-23 14:49:53
http://en.wikipedia.org/wiki/Shunting_yard_algorithm
Kiedyś napisałem ładniejszy (podobny) algorytm (bez kolejki (stanu), ble), ale teraz muszę wyjść z domu, jak wrócę ew coś napisze
P-8738
jacek_k
» 2009-07-28 20:14:21
Mnie się udało stworzyć program, gdzie wklepuje się działanie w postaci (1+2)*3 itd. (potęgowanie jest obsługiwane) z użyciem stosu.
C/C++
#include<iostream>
#include<conio.h>
#include<string>
#include<math.h>
#include<stack>
using namespace std;
struct dane
{
    bool czy_stala;
    double stala;
    char op;
    string zmienna;
};
int priorytet( char op )
{
    if( op == '^' )
         return( 5 );
    else if( op == '*' || op == '/' )
         return( 4 );
    else if( op == '+' || op == '-' )
         return( 3 );
    else if( op == '=' )
         return( 2 );
    else if( op == '(' || op == ')' )
         return( 1 );
    else
         return( 0 );
   
}
double wynik( double a, double b, char op )
{
    if( op == '+' )
         return( a + b );
    else if( op == '-' )
         return( a - b );
    else if( op == '*' )
         return( a * b );
    else if( op == '/' )
         return( a / b );
    else if( op == '^' )
         return( pow( a, b ) );
   
}
void ONP( stack < dane > wejscie, stack < dane >& stos, stack < dane > wyjscie );
void wypelnij( stack < dane >& wejscie, string dzialanie );
void wypelnij_do_obliczen( stack < dane >& wejscie, string dzialanie );
double ONP_wartosc( stack < dane > wejscie );
int main()
{
    /********************************/
    stack < dane > wejscie, stos, wyjscie;
    string dzialanie;
    dane in, temp;
    /********************************/
    dzialanie = "0.5+0.333333+0.25+0.2+0.166666";
    cout << "Oto dzialanie: \"" << dzialanie << "\"" << endl;
    /**********************************************/
    wypelnij( wejscie, dzialanie );
    ONP( wejscie, stos, wyjscie );
    cout << "Oto ONP dla tego dzialania" << endl;
    wejscie = stos;
    int ile = stos.size();
    for( int i = 0; i < ile; i++ )
    {
        in = stos.top();
        if( in.czy_stala == true )
             cout << in.stala;
        else
             cout << in.op;
       
        stos.pop();
        cout << ' ';
    }
    cout << "\nWartosc tego wyrazenia: " << ONP_wartosc( wejscie );
    getch();
}
void wypelnij( stack < dane >& wejscie, string dzialanie )
{
    int j;
    dane a;
    stack < dane > temp;
    for( unsigned i = 0; i < dzialanie.length(); i++ )
    {
        j = i;
        while(( dzialanie[ i ] >= '0' && dzialanie[ i ] <= '9' ) || dzialanie[ i ] == '.' )
        {
            i++;
        }
        if( i - j ) //stala
        {
            a.stala = atof( dzialanie.substr( j, i - j ).c_str() );
            a.czy_stala = true;
            //                        cout<<"Zlapalem stala   : "<<a.stala<<endl;
            --i;
        }
        else if( priorytet( dzialanie[ i ] ) ) //operator
        {
            a.op = dzialanie[ i ];
            a.czy_stala = false;
            //                        cout<<"Zlapalem operator: "<<a.op<<endl;
        }
        temp.push( a );
    }
    //trzeba odwrócić kolejność
    int ile = temp.size();
    for( int i = 0; i < ile; i++ )
    {
        wejscie.push( temp.top() );
        temp.pop();
    }
}
void ONP( stack < dane > wejscie, stack < dane >& stos, stack < dane > wyjscie )
{
    //ONP
    dane in, temp;
    do
    {
        in = wejscie.top();
        if( in.czy_stala == true ) //stała lub zmienna >> wyjście
        {
            wyjscie.push( in );
            //                        cout<<"Wrzucam stala "<<in.stala<<" na wyjscie."<<endl;
        }
        else
        {
            if( in.op == '(' ) //nawias otwierający >> stos
            {
                stos.push( in );
                //                                cout<<"Wrzucam \"(\" na stos."<<endl;
            }
            else if( in.op == ')' )
            {
                while( stos.top().op != '(' )
                {
                    wyjscie.push( stos.top() );
                    stos.pop();
                }
                stos.pop(); //wyrzucam '('
            }
            else if( stos.empty() == true || priorytet( wejscie.top().op ) > priorytet( stos.top().op ) )
            {
                stos.push( in );
                //                                cout<<"Wrzucam \""<<in.op<<"\" na stos."<<endl;
            }
            else
            {
                int op_wejscie = priorytet( in.op ), op_stos;
                op_stos = priorytet( stos.top().op );
                do
                {
                    temp = stos.top();
                    op_stos = priorytet( temp.op );
                    if( op_stos >= op_wejscie )
                    {
                        wyjscie.push( stos.top() );
                        stos.pop();
                    }
                } while( op_stos >= op_wejscie && stos.empty() == false );
               
                stos.push( in );
            }
           
        }
        wejscie.pop();
    } while( !wejscie.empty() );
    /***opróżniamy stos***/
    do
    {
        wyjscie.push( stos.top() );
        stos.pop();
    } while( !stos.empty() );
    /***odwracamy kolejność i wrzucamy na stos***/
    int ile = wyjscie.size();
    for( int i = 0; i < ile; i++ )
    {
        stos.push( wyjscie.top() );
        wyjscie.pop();
    }
    /*******************************************/
}
void wypelnij_do_obliczen( stack < dane >& wejscie, string dzialanie )
{
    int j;
    stack < dane > temp;
    dane pom;
    for( unsigned i = 0; i < dzialanie.length(); i++ )
    {
        j = i;
        if( dzialanie[ i ] >= '0' && dzialanie[ i ] <= '9' )
        {
            while(( dzialanie[ i ] >= '0' && dzialanie[ i ] <= '9' ) || dzialanie[ i ] == '.' )
            {
                i++;
            }
            pom.czy_stala = true;
            pom.stala = atof( dzialanie.substr( j, i - j ).c_str() );
            temp.push( pom );
        }
        else if( priorytet( dzialanie[ i ] ) )
        {
            pom.czy_stala = false;
            pom.op = dzialanie[ i ];
            temp.push( pom );
        }
    }
    int ile = temp.size();
    for( int i = 0; i < ile; i++ )
    {
        wejscie.push( temp.top() );
        temp.pop();
    }
}
double ONP_wartosc( stack < dane > wejscie )
{
    stack < dane > stos;
    dane in, pom;
    double a, b;
    do
    {
        in = wejscie.top();
        if( in.czy_stala == true )
             stos.push( in );
        else
        {
            a = stos.top().stala;
            stos.pop();
            b = stos.top().stala;
            stos.pop();
            pom.stala = wynik( b, a, in.op );
            stos.push( pom );
        }
        wejscie.pop();
    } while( !wejscie.empty() );
   
    return( stos.top().stala );
}
Wiem, że bardzo nakombinowałem (w Internecie znalazłem wersję miesczącą się tylko w stu linijkach) :)
Możecie poprawić formatowanie, bo niestety nie wiem, jak to zrobić :(
P-8853
« 1 »
  Strona 1 z 1