c++スタック実装単純計算機
5336 ワード
/* , , '#', ,
* , , ,
* , , , ,
*/
#include
#include
#include
#include
using namespace std;
const int MAX = 30;
const int DONE = 1;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
//
template
class Stack{
public:
Stack(int MaxStackSize=10);
~Stack() { delete [] stack;}
bool IsEmpty() const {return top==-1;}
bool IsFull() const {return top==MaxTop;}
T Top() const;
Stack& Add(const T& x);
Stack& Del(T& x);
void MakeEmpty(){top=-1;} //
void print(){
for(int i; i < top + 1; i ++){
cout<
Stack::Stack(int MaxStackSize){
MaxTop=MaxStackSize-1;
stack=new T[MaxStackSize];
top=-1;
}
template
Stack& Stack::Add(const T& x){
if(IsFull())
{cout<
Stack& Stack::Del(T& x){
if(IsEmpty())
{cout<
T Stack::Top() const{
return stack[top];
}
//
bool isNum(char c){
if((c > '0'||c == '0')&&(c < '9'||c == '9'))
return true;
else
return false;
}
//
void deleteBlank(string &s){
string::iterator i = s.begin();
while ((i=find(i, s.end(), ' '))!=s.end())
s.erase(i);
}
//
class Calculator{
public:
Calculator(string s);
~Calculator();
int outPriority(char); //
int inPriority(char); //
bool judgePri(char, char); // , 1, 0
int judgePri(char); // '#' -1, ')' 0, 1
void dealNum(); //
int calculate(); //
void setString(string const s){
this->s = '#' + s + '#';
deleteBlank(this->s); //
}
private:
Stack *s_sym; //
Stack *s_num; //
string s;
};
Calculator::Calculator(string s){
this->s = '#' + s + '#';
deleteBlank(this->s);
s_sym = new Stack(MAX);
s_num = new Stack(MAX);
}
Calculator::~Calculator(){
delete s_sym;
delete s_num;
}
int Calculator::outPriority(char symble){
switch(symble){
case '#':
return 0;
case '(':
return 8;
case '+':
return 2;
case '-':
return 2;
case '*':
return 4;
case '/':
return 4;
case '%':
return 4;
case '^':
return 6;
case ')':
return 1;
default:
throw 1;
}
}
int Calculator::inPriority(char symble){
switch(symble){
case '#':
return 0;
case '(':
return 1;
case '+':
return 3;
case '-':
return 3;
case '*':
return 5;
case '/':
return 5;
case '%':
return 5;
case '^':
return 7;
case ')':
return 8;
default:
throw 1;
}
}
bool Calculator::judgePri(char out, char in){
if(outPriority(out) > inPriority(in))
return true;
else
return false;
}
int Calculator::judgePri(char symble){
if(symble == '#')
return -1;
else if(symble == ')')
return 0;
else
return 1;
}
void Calculator::dealNum(){
// , ,
char _temp = 0;
int dtemp1 = 0;
int dtemp2 = 0;
s_sym->Del(_temp);
s_num->Del(dtemp1);
s_num->Del(dtemp2);
switch(_temp){
case '+':
dtemp2 += dtemp1;
break;
case '-':
dtemp2 = dtemp2 - dtemp1;
break;
case '*':
dtemp2 = dtemp2 * dtemp1;
break;
case '/':
if(dtemp1 == 0)
throw 0;
else
dtemp2 = dtemp2 / dtemp1;
break;
case '%':
dtemp2 = dtemp2 % dtemp1;
break;
case '^':
dtemp2 = pow(dtemp2,dtemp1);
break;
default:
throw 1;
}
s_num->Add(dtemp2);
}
int Calculator::calculate(){
for(int i = 0; i < s.size(); i ++){ //
if(isNum(s[i])){
int temp = (int)(s[i]) - 48; //char int ascii , 48
int _temp = 0;
if(i > 0 && isNum(s[i - 1])){
s_num->Del(_temp);
temp = _temp * 10 + temp;
}
s_num->Add(temp);
}else{
char temp = s[i];
if(s_sym->IsEmpty()){
s_sym->Add(temp);
}else{
if(judgePri(temp, s_sym->Top())){
s_sym->Add(temp);
}else if(judgePri(temp) == 1){ // , '#' ')'
while(!judgePri(temp, s_sym->Top())){ // ,
dealNum();
}
s_sym->Add(temp);
}else if (judgePri(temp) == -1){
while(s_sym->Top() != '#'){
dealNum();
}
int result = s_num->Top();
s_sym->MakeEmpty();
s_num->MakeEmpty();
return result;
}
else if(judgePri(temp) == 0){
while(s_sym->Top() != '('){
dealNum();
}
s_sym->Del(temp);
}
}
}
}
}
int main(int argc, char** argv) {
try{
string s = "";
Calculator c(s);
while(DONE){
s = "";
cout<