od joseph-blue-pulasky » 11. 2. 2006 02:58
/*
Toto je moje riesenie, zobral to hned na prvy krat.. myslim ze ten kod je celkom zrozumitelny
*/
Kód: Vybrat vše
#include <string>
#include <iostream>
#include <sstream>
#include <stdlib.h>
using namespace std;
typedef string::iterator strIter;
class Vyraz{
private:
string strVyr;
bool checkVyraz();
bool dosadPremenne( int * n );
public:
Vyraz( char * s );
int vyhodnot( int * n );
int cntSimpleExp( strIter & begin, strIter & end );
string GetVyraz();
};
Vyraz::Vyraz( char * s )
{
//odstran medzery
string tmpVyraz( s );
stringstream novy;
novy << tmpVyraz;
string _tmpVb;
while( novy >> _tmpVb )
strVyr += _tmpVb;
//----------------odstran medzery
strVyr = "(" + strVyr + ")";
}
bool
Vyraz::checkVyraz()
{
int zat=0;
bool ok = true;
bool dolar, oper, minus;
dolar = oper = minus = false;
for( string::iterator i = strVyr.begin(); i != strVyr.end(); i++ )
{
if( *i == '(' )
zat++;
if( *i == ')' )
zat--;
if( *i == '$' ){
if( dolar )
return false;
dolar = true;
oper = false;
} else
if( *i == '-' ){
minus = true;
dolar = false;
oper = false;
} else
if( (*i == '+') || (*i == '*') || (*i == '/') )
{
if( oper )
return false;
oper = true;
dolar = false;
} else {
oper = false;
}
}
if( zat )
return false;
return true;
}
string
Vyraz::GetVyraz()
{
return strVyr;
}
int
Vyraz::vyhodnot( int * n )
{
int zacZatPos,konZatPos;
int vyslPodVyr;
strIter beg,end;
char cVyslPodVyr[1024];
if( !checkVyraz() ){
cerr << "Zle zadany vyraz" << endl;
return 0;
}
dosadPremenne( n );
while( ( zacZatPos = strVyr.find_last_of('(') ) != string::npos )
{
konZatPos = strVyr.find_first_of(')',zacZatPos);
beg = &strVyr[zacZatPos+1];
end = &strVyr[konZatPos];
vyslPodVyr = cntSimpleExp(beg,end);
itoa( vyslPodVyr, cVyslPodVyr, 10 );
strVyr.replace( zacZatPos, (konZatPos - zacZatPos) + 1, cVyslPodVyr );
}
return vyslPodVyr;
}
bool
Vyraz::dosadPremenne( int * n )
{
int dolarPos, dolarVal;
char dolarCharVal;
string dolarRealVal;
char dRV[1024];
while( (dolarPos = strVyr.find_first_of('$')) != string::npos )
{
dolarCharVal = strVyr[dolarPos+1];
dolarVal = atoi( &dolarCharVal );
itoa( n[dolarVal], dRV, 10 );
dolarRealVal.assign( dRV );
strVyr.replace( dolarPos, 2, dolarRealVal );
}
return true;
}
int
Vyraz::cntSimpleExp( strIter & begin, strIter & end )
{
string partStr;
bool unarneMin = true;
int unarneMinStart = 0;
for( strIter i = begin; i != end; i++ )
{
partStr += *i;
}
size_t opPos;
if( (opPos = partStr.find_first_of('+')) != string::npos )
{
//cout << opPos << endl;
strIter l = &partStr[opPos];
return ( cntSimpleExp( partStr.begin(), l ) + cntSimpleExp( l+1, partStr.end() ) );
}
while( unarneMin )
{
if( (opPos = partStr.find_first_of('-', unarneMinStart)) != string::npos )
{
//cout << opPos << endl;
//tu poriesit unarne minus
if( (opPos == 0) || ( partStr[opPos - 1] == '+' ) || ( partStr[opPos - 1] == '*' ) || ( partStr[opPos - 1] == '/' ) )
{
unarneMinStart++;
} else {
strIter l = &partStr[opPos];
return ( cntSimpleExp( partStr.begin(), l ) - cntSimpleExp( l+1, partStr.end() ) );
}
} else {
unarneMin = false;
}
}
if( (opPos = partStr.find_first_of('*')) != string::npos )
{
//cout << opPos << endl;
strIter l = &partStr[opPos];
return ( cntSimpleExp( partStr.begin(), l ) * cntSimpleExp( l+1, partStr.end() ) );
}
if( (opPos = partStr.find_first_of('/')) != string::npos )
{
//cout << opPos << endl;
strIter l = &partStr[opPos];
int lava = cntSimpleExp( partStr.begin(), l );
int prava = cntSimpleExp( l+1, partStr.end() );
if( prava != 0 )
return lava/prava;
else
cerr << "Delenie nulou!!!" << endl;
return 0;
}
stringstream ret;
ret << partStr;
int intRet;
ret >> intRet;
return intRet;
//return 0;
}
int main(int argc, char ** argv){
// Vyraz x( "1 + 1 * ( 2 - - $2 + $0)" );
Vyraz x( "4" );
cout << x.GetVyraz() << endl;
int pole[9];
pole[0] = 54321;
pole[2] = 12345;
x.vyhodnot( pole );
cout << x.GetVyraz() << endl;
}
/*
[b]Toto je moje riesenie, zobral to hned na prvy krat.. myslim ze ten kod je celkom zrozumitelny[/b]
*/
[code]#include <string>
#include <iostream>
#include <sstream>
#include <stdlib.h>
using namespace std;
typedef string::iterator strIter;
class Vyraz{
private:
string strVyr;
bool checkVyraz();
bool dosadPremenne( int * n );
public:
Vyraz( char * s );
int vyhodnot( int * n );
int cntSimpleExp( strIter & begin, strIter & end );
string GetVyraz();
};
Vyraz::Vyraz( char * s )
{
//odstran medzery
string tmpVyraz( s );
stringstream novy;
novy << tmpVyraz;
string _tmpVb;
while( novy >> _tmpVb )
strVyr += _tmpVb;
//----------------odstran medzery
strVyr = "(" + strVyr + ")";
}
bool
Vyraz::checkVyraz()
{
int zat=0;
bool ok = true;
bool dolar, oper, minus;
dolar = oper = minus = false;
for( string::iterator i = strVyr.begin(); i != strVyr.end(); i++ )
{
if( *i == '(' )
zat++;
if( *i == ')' )
zat--;
if( *i == '$' ){
if( dolar )
return false;
dolar = true;
oper = false;
} else
if( *i == '-' ){
minus = true;
dolar = false;
oper = false;
} else
if( (*i == '+') || (*i == '*') || (*i == '/') )
{
if( oper )
return false;
oper = true;
dolar = false;
} else {
oper = false;
}
}
if( zat )
return false;
return true;
}
string
Vyraz::GetVyraz()
{
return strVyr;
}
int
Vyraz::vyhodnot( int * n )
{
int zacZatPos,konZatPos;
int vyslPodVyr;
strIter beg,end;
char cVyslPodVyr[1024];
if( !checkVyraz() ){
cerr << "Zle zadany vyraz" << endl;
return 0;
}
dosadPremenne( n );
while( ( zacZatPos = strVyr.find_last_of('(') ) != string::npos )
{
konZatPos = strVyr.find_first_of(')',zacZatPos);
beg = &strVyr[zacZatPos+1];
end = &strVyr[konZatPos];
vyslPodVyr = cntSimpleExp(beg,end);
itoa( vyslPodVyr, cVyslPodVyr, 10 );
strVyr.replace( zacZatPos, (konZatPos - zacZatPos) + 1, cVyslPodVyr );
}
return vyslPodVyr;
}
bool
Vyraz::dosadPremenne( int * n )
{
int dolarPos, dolarVal;
char dolarCharVal;
string dolarRealVal;
char dRV[1024];
while( (dolarPos = strVyr.find_first_of('$')) != string::npos )
{
dolarCharVal = strVyr[dolarPos+1];
dolarVal = atoi( &dolarCharVal );
itoa( n[dolarVal], dRV, 10 );
dolarRealVal.assign( dRV );
strVyr.replace( dolarPos, 2, dolarRealVal );
}
return true;
}
int
Vyraz::cntSimpleExp( strIter & begin, strIter & end )
{
string partStr;
bool unarneMin = true;
int unarneMinStart = 0;
for( strIter i = begin; i != end; i++ )
{
partStr += *i;
}
size_t opPos;
if( (opPos = partStr.find_first_of('+')) != string::npos )
{
//cout << opPos << endl;
strIter l = &partStr[opPos];
return ( cntSimpleExp( partStr.begin(), l ) + cntSimpleExp( l+1, partStr.end() ) );
}
while( unarneMin )
{
if( (opPos = partStr.find_first_of('-', unarneMinStart)) != string::npos )
{
//cout << opPos << endl;
//tu poriesit unarne minus
if( (opPos == 0) || ( partStr[opPos - 1] == '+' ) || ( partStr[opPos - 1] == '*' ) || ( partStr[opPos - 1] == '/' ) )
{
unarneMinStart++;
} else {
strIter l = &partStr[opPos];
return ( cntSimpleExp( partStr.begin(), l ) - cntSimpleExp( l+1, partStr.end() ) );
}
} else {
unarneMin = false;
}
}
if( (opPos = partStr.find_first_of('*')) != string::npos )
{
//cout << opPos << endl;
strIter l = &partStr[opPos];
return ( cntSimpleExp( partStr.begin(), l ) * cntSimpleExp( l+1, partStr.end() ) );
}
if( (opPos = partStr.find_first_of('/')) != string::npos )
{
//cout << opPos << endl;
strIter l = &partStr[opPos];
int lava = cntSimpleExp( partStr.begin(), l );
int prava = cntSimpleExp( l+1, partStr.end() );
if( prava != 0 )
return lava/prava;
else
cerr << "Delenie nulou!!!" << endl;
return 0;
}
stringstream ret;
ret << partStr;
int intRet;
ret >> intRet;
return intRet;
//return 0;
}
int main(int argc, char ** argv){
// Vyraz x( "1 + 1 * ( 2 - - $2 + $0)" );
Vyraz x( "4" );
cout << x.GetVyraz() << endl;
int pole[9];
pole[0] = 54321;
pole[2] = 12345;
x.vyhodnot( pole );
cout << x.GetVyraz() << endl;
}[/code]