Ultima modifica:
Concettualmente sembra semplice, ma alla fine si rivela una sfida trovare un modo veramente pulito per farlo.
Il codice non l'hai capito al colpo perché non è scritto in modo pulito, si vede che ci ha ragionato sopra mentre lo scriveva e aveva in mente fin da subito un algoritmo da usare.
Qui ho commentato quello che succede per far vedere come ci sia qualcosa che non quadra nel ragionamento generale, alla fine per funzionare funziona (con le dovute restrizioni), ma si capisce che il codice è scritto è scritto molto "sul momento"
A mio parere con un algoritmo strutturato in questo modo l'OOP non porta grossi vantaggi, anzi...
Se si vuole sfruttare l'OOP bisogna riscriverlo e ripensarlo da zero, con un metodo di risoluzione completamente differente da questo.
Secondo me conviene prima sistemare il codice per renderlo più pulito, poi si riparte da quello ripulito per provare a sistemare il problema delle precedenze. Già risistemando quel pezzetto che ho commentato sopra (che era giusto il primo che ho esaminato, probabilmente ci sono "problemi" di quel tipo un po' ovunque) avresti dei valori meno campati per aria (ma comunque sbagliati) in caso di operazioni del tipo 1+2*3.
Ho letto il codice e ho dovuto leggerlo diverse volte per capirci qualcosa (può darsi sia un problema mio, come dicevo prima sono a digiuno di programmazione). Visto che stai scrivendo in C++ direi che è meglio ripensarlo in OOP, perchè così com'è, anche se non sono molte righe, diventa un problema aggiungere nuovi simboli e nuove operazioni, oltre al fatto che trovare i bug non è facile. Parti dal caso generale (insieme di operatori ed addendi) e man mano implementando le classi arrivi ai singoli casi.
Il codice non l'hai capito al colpo perché non è scritto in modo pulito, si vede che ci ha ragionato sopra mentre lo scriveva e aveva in mente fin da subito un algoritmo da usare.
Qui ho commentato quello che succede per far vedere come ci sia qualcosa che non quadra nel ragionamento generale, alla fine per funzionare funziona (con le dovute restrizioni), ma si capisce che il codice è scritto è scritto molto "sul momento"
Codice:
float resolve_cast(string esp)
{
string tmp=esp;
vector<char> op;
vector<float> vals;
float ris;
int plus=0; // inutile
for(int i=0; i<esp.size(); i++)
{
if(esp[i]=='+' || esp[i]=='-' || esp[i]=='*' || esp[i]=='/')
op.push_back(esp[i]); // metto in op tutti gli operatori
}
if(op[0]=='+' || op[0]=='-') // se il primo operatore è + o -
{
op.resize(0); // cancella tutti gli operatori --- ma allora a cosa mi è servito tutto quello che ho fatto prima?
// potevo fare la stessa cosa in modo molto più semplice.
for(int i=0; i<tmp.size(); i++)
{
if(tmp[i]=='+' || tmp[i]=='-') // qui dovrebbero esserci anche tutti gli altri simboli (*, / e parentesi), altrimenti me li mangia conv_str --- (*)
{
vals.push_back(conv_str(tmp.substr(0, i)));
tmp=tmp.substr(i+1, (tmp.size()-1));
i=0;
}
}
vals.push_back(conv_str(tmp)); // e questo non dovrebbe esistere, basta mettere anche '\0' a (*) e far fare tutto al for
for(int i=0; i<esp.size(); i++) // avevo letto tutti gli operatori e li avevo messi in op
{ // poi ho visto che il primo era un for così sono entrato nell'if e ho azzerato op.
if(esp[i]=='+' || esp[i]=='-') // ora mi ripasso tutti gli operatori perché mi accorgo che ho ancora bisogno di informazioni sugli operatori
op.push_back(esp[i]); // ma io sapevo già tutto sugli operatori, avevo eliminato dei dati che mi servivano ancora.
}
if(op[0]=='+') // (***)
ris=vals[0]+vals[1];
else if(op[0]=='-')
ris=vals[0]-vals[1];
if(vals.size()==2) // non è che serva più di tanto con il codice che c'è sotto --- (**)
return ris;
for(int i=1; i<op.size(); i++) // (**) se ho un solo operatore (visto che gli operatori sono solo + e -) ritorno giustamente ris
{ // ma ancora meglio si può unire (***) a questo for
if(op[i]=='+')
ris=ris+vals[i+1];
else if(op[i]=='-')
ris=ris-vals[i+1];
}
return ris;
}
// CONTINUA (il resto è praticamente identico al pezzo sopra, quindi ho evitato di ripetermi)
A mio parere con un algoritmo strutturato in questo modo l'OOP non porta grossi vantaggi, anzi...
Se si vuole sfruttare l'OOP bisogna riscriverlo e ripensarlo da zero, con un metodo di risoluzione completamente differente da questo.
So che funziona con qualche stringa ed é pieno di bug, ma mantenendomi sulla falsa riga di questo algoritmo potrei migliorarlo in che modo?
Secondo me conviene prima sistemare il codice per renderlo più pulito, poi si riparte da quello ripulito per provare a sistemare il problema delle precedenze. Già risistemando quel pezzetto che ho commentato sopra (che era giusto il primo che ho esaminato, probabilmente ci sono "problemi" di quel tipo un po' ovunque) avresti dei valori meno campati per aria (ma comunque sbagliati) in caso di operazioni del tipo 1+2*3.