#include <iostream>
using namespace std;
#define PRINTIT(P,S) cout << i << " " << S \
<< " " << j << " = " << (i P j) << endl;
int main()
{
int i,j;
for (i=0;i<=1;++i) for (j=0;j<=1;++j) {
PRINTIT(&,"&");
PRINTIT(|,"|");
PRINTIT(^,"^");
}
}
|
static int atoi(const char* s)
{
if (!*s || (!isdigit(*s) && *s != '-' && *s != '+'))
return 0;
int i;
if (!strncmp(s,"0x",2))
return sscanf(s,"%x",&i) == 1 ? i : 0;
if (!strncmp(s,"0",1))
return sscanf(s,"%o",&i) == 1 ? i : 0;
return sscanf(s,"%d",&i) == 1 ? i : 0;
}
|
#include <cmath>
#include <cctype>
#include <iostream>
#include <string>
#include <map>
using namespace std;
#pragma warning(disable : 4786)
struct CExpr {
typedef double (*FType)(double);
virtual ~CExpr(){};
virtual double Value()const = 0;
static map<string,double> s_val; // 変数とその値
static map<string,FType> s_func; // 関数
};
static inline void eatwhite(istream& cin)
{
char c;
while (cin.get(c)) if (c != ' ') {cin.putback(c); break;}
}
class CBin : public CExpr {
protected:
CExpr* m_left;
CExpr* m_right;
CBin(CExpr* p,CExpr* q) : m_left(p), m_right(q) {}
public:
enum Type {Add,Sub,Mul,Div};
~CBin(){delete m_left; delete m_right;}
static CExpr* New(CExpr* p,CExpr* q,Type t);
};
struct CAdd : public CBin {
CAdd(CExpr* p,CExpr* q) : CBin(p,q) {}
virtual double Value()const
{return m_left->Value() + m_right->Value();}
};
struct CSub : public CBin {
CSub(CExpr* p,CExpr* q) : CBin(p,q) {}
virtual double Value()const
{return m_left->Value() - m_right->Value();}
};
struct CMul : public CBin {
CMul(CExpr* p,CExpr* q) : CBin(p,q) {}
virtual double Value()const
{return m_left->Value() * m_right->Value();}
};
struct CDiv : public CBin {
CDiv(CExpr* p,CExpr* q) : CBin(p,q) {}
virtual double Value()const{double d = m_right->Value();
return m_left->Value() / (d ? d : 1) ;}
};
class CNega : public CExpr {
CExpr* m_ptr;
CNega(CExpr* p) : m_ptr(p) {}
public:
~CNega(){delete m_ptr;}
virtual double Value()const{return -m_ptr->Value();}
static CExpr* New(CExpr* p){return p ? new CNega(p) : 0;}
};
class CNum : public CExpr {
double m_val;
public:
CNum(double d) : m_val(d) {}
virtual double Value()const{return m_val;}
};
class CVar : public CExpr {
string m_name;
public:
CVar(const string& s) : m_name(s) {}
virtual double Value()const{return CExpr::s_val[m_name];}
};
class CSet : public CExpr {
string m_name;
CExpr* m_ptr;
CSet(const string& s,CExpr* p) : m_name(s), m_ptr(p) {}
public:
~CSet(){delete m_ptr;}
virtual double Value()const
{return CExpr::s_val[m_name] = m_ptr->Value();}
static CExpr* New(string s,CExpr* p){return p ? new CSet(s,p) : 0;}
};
class CFunc : public CExpr {
string m_name;
CExpr* m_ptr;
CFunc(const string& s,CExpr* p) : m_name(s), m_ptr(p) {}
public:
~CFunc(){delete m_ptr;}
virtual double Value()const
{return CExpr::s_func[m_name](m_ptr->Value());}
static CExpr* New(string s,CExpr* p){return p ? new CFunc(s,p) : 0;}
};
map<string,double> CExpr::s_val;
map<string,CExpr::FType> CExpr::s_func;
CExpr* CBin::New(CExpr* p,CExpr* q,Type t)
{
if (!p || !q) {
delete p;
delete q;
return 0;
}
CExpr* r = 0;
switch (t) {
case Add: r = new CAdd(p,q); break;
case Sub: r = new CSub(p,q); break;
case Mul: r = new CMul(p,q); break;
case Div: r = new CDiv(p,q); break;
}
return r;
}
CExpr* GetExpr();
CExpr* GetPrim()
{
CExpr* p = 0;
eatwhite(cin);
char c;
cin.get(c);
if (c == '-') {
p = CNega::New(GetPrim());
} else if (c == '(') {
p = GetExpr();
eatwhite(cin);
if (cin.peek() == ')') cin.ignore();
else {delete p; p = 0;}
} else if (isdigit(c)) {
cin.putback(c);
double d;
cin >> d;
p = new CNum(d);
} else if (isalpha(c)) {
string s(&c,1);
while (cin.get(c) && isalpha(c)) s += c;
if (c == ' ') {eatwhite(cin); cin.get(c);}
if (c == '=') p = CSet::New(s,GetExpr());
else if (c == '(') {
p = CFunc::New(s,GetExpr());
eatwhite(cin);
if (cin.peek() == ')') cin.ignore();
else {delete p; p = 0;}
} else p = new CVar(s), cin.putback(c);
}
return p;
}
CExpr* GetTerm()
{
CExpr* p = GetPrim();
while (p) {
eatwhite(cin);
int c = cin.peek();
if (c != '*' && c != '/') break;
cin.ignore();
p = CBin::New(p,GetPrim(),c == '*' ? CBin::Mul : CBin::Div);
}
return p;
}
CExpr* GetExpr()
{
CExpr* p = GetTerm();
while (p) {
eatwhite(cin);
int c = cin.peek();
if (c != '+' && c != '-') break;
cin.ignore();
p = CBin::New(p,GetTerm(),c == '+' ? CBin::Add : CBin::Sub);
}
return p;
}
int main()
{
CExpr::s_val["pi"] = 3.1415926535897932385;
CExpr::s_val["e"] = 2.7182818284590452354;
CExpr::s_func["sqrt"] = sqrt;
CExpr::s_func["log"] = log;
CExpr::s_func["sin"] = sin;
CExpr::s_func["cos"] = cos;
while (cin) {
CExpr* p = GetExpr();
if (p && cin.peek() == '\n') {
cin.ignore();
double d = p->Value();
cout << d << endl;
delete p;
continue;
}
cout << "Error before [";
char c;
while (cin.get(c)) {
if (c == '\n') break;
cout << c;
}
cout << "]\n";
}
}
|