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: #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; }
|
|
Kinexity |
» 2017-11-03 20:37:12 Kod jest całkowicie nieczytelny - te jedno- i dwuliterowe nazwy nie mówią nic. |
|
Witam321 Temat założony przez niniejszego użytkownika |
Przepraszam za takie niedociągnięcie » 2017-11-03 21:56:45 #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; }
|
|
pekfos |
» 2017-11-03 22:39:02 Wyrażenie nie jest poprawnie konwertowane. Wpisz 12+3. |
|
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ć? |
|
michal11 |
» 2017-11-04 15:06:06 Odwrotna Notacja Polska. |
|
pekfos |
» 2017-11-04 15:10:12 Nie trzymaj danych w jednym char. I co z nią? Poza tym, że jest już zaimplementowana u niego w kodzie? |
|
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 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. |
|
« 1 » |