Calcolatrice con 3+ valori

7

Sono nuovo di c ++ e sto facendo il buon vecchio calcolatore. Sono passato da un calcolatore a 2 valori a un calcolatore a 3 valori e mi sono chiesto come sia possibile creare un calcolatore a 10 cifre (usando esclusivamente +, -, *, /) che non codifica per sempre .. Ho una dichiarazione if che restituisce cosa succede se gli operatori sono + e + o + e - ecc. e se dovessi passare al valore 4, scriverei 64 if e il valore 5 sarebbe 256 se le istruzioni.

C'è un modo per cambiarlo in modo tale da non richiedere la scrittura di così tante istruzioni if?

Ecco le mie parti importanti del codice:

Calculator.cpp:

#include "stdafx.h"
#include <iostream>
#include "headers.h"
using namespace std;

int main()
{
int nInput1 = GetUserInput();
char chOperation = GetMathematicalOperation();
{
    if (chOperation == '=')
    {
        cout << "The answer is: " << nInput1 << endl;
        return 0;
    }
}
int nInput2 = GetUserInput();
char chOperation2 = GetMathematicalOperation();
{
    if (chOperation2 == '=')
    {
        int nResult = CalculateResult(nInput1, chOperation, nInput2);
        cout << "The answer is: " << nResult << endl;
        return 0;
    }
}

int nInput3 = GetUserInput();

int nResult = CalculateResult2(nInput1, chOperation, nInput2, chOperation2, nInput3);

PrintResult(nResult);
}

CalculateResult.cpp:

#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;


int CalculateResult(int nX, char chOperation, int nY)
{
if (chOperation == '+')
    return nX + nY;
if (chOperation == '-')
    return nX - nY;
if (chOperation == '*')
    return nX * nY;
if (chOperation == '/')
    return nX / nY;

return 0;
}

GetMathematicalOperation.cpp:

#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;

char GetMathematicalOperation()
{
cout << "Please enter an operator (+,-,*,/ or =): ";

char chOperation;
cin >> chOperation;
return chOperation;
}

CalculateResult2.cpp:

#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;


int CalculateResult2(int nX, char chOperation, int nY, char chOperation2, int nZ)
{
if (chOperation == '+' && chOperation2 == '+')
    return nX + nY + nZ;
if (chOperation == '+' && chOperation2 == '-')
    return nX + nY - nZ;
if (chOperation == '+' && chOperation2 == '*')
    return nX + nY * nZ;
if (chOperation == '+' && chOperation2 == '/')
    return nX + nY / nZ;

if (chOperation == '-' && chOperation2 == '+')
    return nX - nY + nZ;
if (chOperation == '-' && chOperation2 == '-')
    return nX - nY - nZ;
if (chOperation == '-' && chOperation2 == '*')
    return nX - nY * nZ;
if (chOperation == '-' && chOperation2 == '/')
    return nX - nY / nZ;

if (chOperation == '*' && chOperation2 == '+')
    return nX * nY + nZ;
if (chOperation == '*' && chOperation2 == '-')
    return nX * nY - nZ;
if (chOperation == '*' && chOperation2 == '*')
    return nX * nY * nZ;
if (chOperation == '*' && chOperation2 == '/')
    return nX * nY / nZ;

if (chOperation == '/' && chOperation2 == '+')
    return nX / nY + nZ;
if (chOperation == '/' && chOperation2 == '-')
    return nX / nY - nZ;
if (chOperation == '/' && chOperation2 == '*')
    return nX / nY * nZ;
if (chOperation == '/' && chOperation2 == '/')
    return nX / nY / nZ;
return 0;
}
    
posta Matt 27.12.2013 - 15:12
fonte

2 risposte

11

La programmazione riguarda esclusivamente strutture dati e algoritmi. Nel tuo Ad esempio, non ci sono dati apparenti: le tue funzioni sono lavorando con input utente non elaborato e fornendo direttamente la risposta, senza introducendo qualsiasi struttura intermediario per rappresentare la logica di il calcolo.

Come conseguenza pratica dell'equazione ben nota

programs = data structures + algorithms

l'assenza di una struttura dati adeguata ti costringe a rappresentare la logica del calcolo nella parte algoritmi , cioè, nel tuo codice. Questo è il motivo per cui il tuo codice sembra così complicato, con quello gran numero di if s. E il tuo istinto è giusto, ogni volta che sei il codice sembra complicato, suonerà un campanello che urla c'è qualcosa di sbagliato e che qualcosa è in genere che stai usando la struttura dei dati sbagliata.

L'astrazione che ti manca qui è quella che viene chiamata algebrica espressione, che puoi considerare come un'espressione non valutata. Così ora, risponderò alla tua domanda su come scrivere la tua calcolatrice, ma io consiglia vivamente di cambiare il problema e di scriverne un altro tipo di calcolatrice.

Ecco i passaggi per scrivere una calcolatrice che supporti arbitrariamente espressioni complicate:

  1. Implementa alberi di espressioni binarie come classe astratta Expression con due discendenti concreti, un Leaf per il numeri (foglie) e un altro Node per le operazioni (nodi).

  2. Segui il cosiddetto pattern Visitor per scrivere un valutatore per le tue espressioni Vuoi scrivere un valutatore prendendo un Expression e valutandolo, lo schema Visitor è il comune modo per capire se Expression è in realtà un Leaf o un Node .

  3. Scrivi un parser per trasformare l'input dell'utente in un espressione. Questo è un compito noioso, ma ci sono strumenti automatici per aiutarti, come Bison .

Se sei un principiante, questi tre passaggi sono impegnativi perché loro ti esporrà a molti nuovi concetti di programmazione simultaneamente: strutture dati astratte, input / output e parser. Un esercizio molto più trattabile è quello di scrivere un calcolatore di reverse polish notation (RPN) con tale a calcolatrice, invece di dire il computer per calcolare 3 + 4 * 5 tu dici di calcolare 4 5 * 3 + che semplifica enormemente la logica del programma:

  1. Invece di lavorare con alberi di espressioni binarie e quindi con classi astratte e concrete, lavori solo con una pila di numeri: la struttura dei dati utilizzata è molto più semplice.

  2. A causa di 1., non è necessario utilizzare il visitatore contorto modello.

  3. Leggere l'input e valutarlo è molto più semplice in RPN che nella solita notazione infissa, perché non ce n'è bisogno prestare attenzione alle regole di priorità.

Una volta che sei soddisfatto del tuo esempio, puoi cercare il programma bc(1) su una scatola Linux, è una notazione completa di smalto inverso calcolatrice, potresti voler studiare le sue caratteristiche o il suo codice (in C) a trova più sfide!

    
risposta data 27.12.2013 - 16:04
fonte
7

Probabilmente ciò che vuoi provare per primo è un calcolatore RPN . Con RPN, spingi i numeri su uno stack , quindi li spegni quando qualcuno entra in un operatore. È più semplice da implementare rispetto a un calcolatore infisso, ma ti consente di scrivere espressioni arbitrariamente lunghe e di valutarle man mano che procedi.

Il prossimo passo sarebbe utilizzare l'algoritmo smistamento dei piazzali per convertire un'espressione infissa in un'espressione RPN. È troppo lungo per includere i dettagli qui, ma è un algoritmo ben noto.

Il prossimo passo sarebbe scrivere un'espressione completa parser , che è un argomento abbastanza avanzato, ma estremamente flessibile e utile. Ci sono molti strumenti disponibili per aiutarti a fare questo.

In ogni caso, probabilmente vorresti fare delle ricerche su pile, code e alberi, e magari provare un paio di programmi di test usando una pila prima di affrontare nuovamente una calcolatrice. C ++ ha un'implementazione stack nella sua libreria standard che sarebbe un buon punto di partenza per imparare.

    
risposta data 27.12.2013 - 15:37
fonte

Leggi altre domande sui tag