- //caculator.h
- #ifndef _CACULATOR_
- #define _CACULATOR_
- #include <map>
- #include <stack>
- #include <string>
- #include <cstdlib>
- class transfer
- {
- public:
- transfer(const char* str):expr(str){}
- template<typename T>
- operator T () const { return T(expr.c_str()); }
- operator double () const { return atof(expr.c_str()); }
- operator int () const { return atoi(expr.c_str()); }
- operator float () const { return atof(expr.c_str()); }
- private:
- std::string expr;
- };
- template <typename T>
- class caculator
- {
- public:
- caculator():result(T(0)){
- if(priority.empty())
- setmap();
- }
- ~caculator(){}
- operator T(){ return result;}
- T caculate(const char *expr){
- const char * p=expr;
- while(*p!='\\0'){
- int n=0;
- if(tooken_operand(p,&n)){
- s.assign(p,p+n);
- num.push((T)transfer(s.c_str()));
- p+=n;
- continue;
- }
- else if(tooken_operator(p)){
- if(op.empty()||*p=='(')
- op.push(*p);
- else{
- while(!op.empty()){
- if(priority[*p]<=priority[op.top()])
- work_step();
- else
- break;
- }
- op.push(*p);
- }
- ++p;
- continue;
- }
- else{
- exit(-1);
- }
- }
- while(work_step());
- result=num.top();
- num.pop();
- return result;
- }
- private:
- T result;
- std::string s;
- std::stack<T> num;
- std::stack<char> op;
- private:
- bool tooken_operand(const char *p,int *n){
- const char *ptr=p;
- *n=0;
- while(*ptr!='\\0'){
- if((*ptr>'9'||*ptr<'0')&&(*ptr!='.'))
- break;
- ++(*n);
- ++ptr;
- }
- if(*n>0)
- return true;
- return false;
- }
- bool tooken_operator(const char *p){
- switch(*p){
- case '+':
- case '-':
- case '*':
- case '/':
- case '(':
- case ')':
- return true;
- default:
- return false;
- }
- }
- bool work_step(){
- if(op.empty())
- return false;
- char c=op.top();
- op.pop();
- T tmp;
- switch(c){
- case ')':
- while(op.top()!='(') work_step();
- op.pop();
- break;
- case '(':
- break;
- default:
- tmp=num.top();
- num.pop();
- switch(c){
- case '+':
- num.top()+=tmp;
- break;
- case '-':
- num.top()-=tmp;
- break;
- case '*':
- num.top()*=tmp;
- break;
- case '/':
- num.top()/=tmp;
- break;
- }
- break;
- }
- return true;
- }
- public:
- static void setmap();
- static std::map<char,int> priority;
- };
- template <typename T>
- std::map<char,int> caculator<T>::priority;
- template <typename T>
- void caculator<T>::setmap()
- {
- priority.insert(pair<char,int>('(',1));
- priority.insert(pair<char,int>('+',2));
- priority.insert(pair<char,int>('-',3));
- priority.insert(pair<char,int>('*',4));
- priority.insert(pair<char,int>('/',5));
- priority.insert(pair<char,int>(')',6));
- }
- #endif
- //main.cpp
- #include <iostream>
- #include "caculator.h"
- using namespace std;
- int main()
- {
- caculator<float> ca;
- ca.caculate("3-2-5+4*(3-(1+1))/2");
- cout<<ca;
- return 0;
- }
- //该片段来自于http://www.codesnippet.cn/detail/021220137650.html
来源: http://www.codesnippet.cn/detail/021220137650.html