Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- Author: Pablo Moreno Olalla
- Email address: darthbrevu@yahoo.es
- */
- #include "BigNumber.h"
- #include <list>
- #include <cstdio>
- #include <string>
- #include <iostream>
- #include <algorithm>
- using namespace std;
- inline bool add(const list<Number> &in,Number &out) {
- if (in.empty()) return false;
- list<Number>::const_iterator it=in.begin();
- out=*it;
- list<Number>::const_iterator end=in.end();
- for (++it;it!=end;++it) out+=*it;
- return true;
- }
- inline bool mul(const list<Number> &in,Number &out) {
- if (in.empty()) return false;
- list<Number>::const_iterator it=in.begin();
- out=*it;
- list<Number>::const_iterator end=in.end();
- for (++it;it!=end;++it) out*=*it;
- return true;
- }
- inline bool sub(const list<Number> &in,Number &out) {
- if (in.empty()) return false;
- list<Number>::const_reverse_iterator it=in.rbegin();
- out=*it;
- out.flipSign();
- list<Number>::const_reverse_iterator rend=in.rend();
- for (++it;it!=rend;++it) out+=*it;
- return true;
- }
- string numberChrs="+-0123456789";
- string validChars="=#@";
- bool parse(const string &in,Number &out,size_t &pos);
- bool parseNumber(const string &in,Number &out,size_t &pos) {
- size_t pos2=in.find_first_not_of(numberChrs,pos);
- if (pos2==string::npos) pos2=in.size();
- try {
- out=Number(in.substr(pos,pos2-pos));
- } catch (const runtime_error &) {
- return false;
- }
- pos=pos2;
- return true;
- }
- bool parseExpr(const string &in,Number &out,size_t &pos) {
- //Whenever this method is called, we're sure that the first character is "^". So, skip it.
- ++pos;
- while (pos<in.size()&&in[pos]==' ') ++pos;
- if (pos==in.size()) return false;
- char op=in[pos];
- if (validChars.find(op)==string::npos) return false;
- ++pos;
- list<Number> parsed;
- Number tmpN;
- for (;;) {
- while (pos<in.size()&&in[pos]==' ') ++pos;
- if (pos==in.size()) return false;
- if (in[pos]=='$') break;
- if (!parse(in,tmpN,pos)) return false;
- parsed.push_back(tmpN);
- }
- ++pos; //So we point just AFTER the '$'.
- if (op=='=') return add(parsed,out);
- else if (op=='#') return mul(parsed,out);
- else if (op=='@') return sub(parsed,out);
- }
- bool parse(const string &in,Number &out,size_t &pos) {
- if (pos>=in.size()) return false;
- while (in[pos]==' ') {
- ++pos;
- if (pos>=in.size()) return false;
- }
- //Not sure if this is correct.
- if (in[pos]=='^') return parseExpr(in,out,pos);
- else if (numberChrs.find(in[pos])) return parseNumber(in,out,pos);
- else return false;
- }
- int main(int argc,char **argv) {
- //The first two lines are not strictly necessary, but make the code a little more handy.
- if (argc>=2) freopen(argv[1],"r",stdin);
- if (argc>=3) freopen(argv[2],"w",stdout);
- string tmp;
- Number n;
- size_t pos;
- do {
- pos=0;
- getline(cin,tmp);
- if (parse(tmp,n,pos)) cout<<static_cast<string>(n)<<endl;
- } while (!cin.eof());
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement