스택 기반 수식 계산기 / 중위식 변환 (Expression Evaluation based stack / Convert Infix Expression to Postfix & Prefix Expression)

Sample

  • input sample
10
2+4*5-3
(2+4)*(5-3)
2-5*3+1
2-5*3+1
5/3
2-5*3+1
2-5*3+1
2-5*3+1
2-5*3+1
2-5*3+1
  • output sample
10

Expression (1/10)
Infix:  2+4*5-3
Postfix: 245*+3-
Result:  19
Infix:  ((2+(4*5))-3)

Expression (2/10)
Infix:  (2+4)*(5-3)
Postfix: 24+53-*
Result:  12
Infix:  ((2+4)*(5-3))

Expression (3/10)
Infix:  2-5*3+1
Postfix: 253*-1+
Result:  -12
Infix:  ((2-(5*3))+1)

Expression (4/10)
Infix:  2-5*3+1
Postfix: 253*-1+
Result:  -12
Infix:  ((2-(5*3))+1)

Expression (5/10)
Infix:  5/3
Postfix: 53/
Result:  1.66667
Infix:  (5/3)

Expression (6/10)
Infix:  2-5*3+1
Postfix: 253*-1+
Result:  -12
Infix:  ((2-(5*3))+1)

Expression (7/10)
Infix:  2-5*3+1
Postfix: 253*-1+
Result:  -12
Infix:  ((2-(5*3))+1)

Expression (8/10)
Infix:  2-5*3+1
Postfix: 253*-1+
Result:  -12
Infix:  ((2-(5*3))+1)

Expression (9/10)
Infix:  2-5*3+1
Postfix: 253*-1+
Result:  -12
Infix:  ((2-(5*3))+1)

Expression (10/10)
Infix:  2-5*3+1
Postfix: 253*-1+
Result:  -12
Infix:  ((2-(5*3))+1)

Source Code

main.cpp

cpp
// Expression Evaluation
#include "Calc.h"

int main()
{


 try
 {

  Calc* test;

  char exp[11][MAX_CHAR];
  int i,j,k;
 
  for(i=0;i<11;i++)
   for(j=0;j<MAX_CHAR;j++)
    exp[i][j]=NULL;

 
  ifstream file1;
  file1.open("input.txt");
 
  i=0;k=0;
  while(file1)
  {
   if(i>=11) break;
   file1.getline(exp[i],MAX_CHAR);
   
   i++;
  }
  file1.close();
  
  ofstream file2;
  file2.open("output.txt");
 
  k=0;
 
  for(j=0;j<=i;j++)
  {
   if(exp[j][0]==NULL||exp[j][0]=='\n') // NULL expression
   {
    i--;
   }
   else if((exp[j][1]==NULL||exp[j][1]=='\n')||(exp[j][2]==NULL||exp[j][2]=='\n')) // a number
   {
    i--;
   }  
  }

  for(j=0;j<=i;j++)
  {
   if((exp[j][1]==NULL||exp[j][1]=='\n')||(exp[j][2]==NULL||exp[j][2]=='\n')) // a number 
   {
   file2 << exp[j] << endl << endl;
   continue; 
   }


   test = new Calc(INFIX,exp[j]); // INFIX expression
   file2 << "Expression (" << k+1 << "/" << i << ")" << endl
    << "Infix:  " << test->PrintExp() << endl;
     
   test->Convert(POSTFIX);
   file2 << "Postfix: " << test->PrintExp() << endl;
   file2 << "Result:  " << test->Evaluate() << endl;

   test->Convert(INFIX);
   file2 << "Infix:  " << test->PrintExp() << endl << endl;

   delete test;
   k++;
  }

  file2.close();

  cout << "Please open output.txt" << endl;

 }
 catch(char* e)
 {
  cout << e << endl;
 }


 return 0;

}

Calc.h

cpp
// Calc.h
#ifndef CALC_H
#define CALC_H

#define INFIX 0
#define POSTFIX 1

#define MAX_CHAR 100 // maximum size of the expression

#include <iostream> 
#include <stack> // use class stack<T>
#include <fstream> // use class ifstream, ofstream

using namespace std;

class Calc
{
private:
 
 int type; // INFIX or POSTFIX
 char* expression; // ex) 2+3*4 , 234*+, (2+(3*4))

public:
 Calc(int n_type,char* n_exp); // n_type: type of expression , n_exp: new expression line
 // Because array of expressions is static array, this class has default destructor.

 void Convert(int c_type); // ex) Convert(INFIX): if type==POSTFIX, convert POSTFIX to INFIX.
 double Evaluate(); // evaluate the expression
 char* PrintExp(); // return pointer of the expression

};



#endif

Calc.cpp

cpp
//Calc.cpp
#include "Calc.h"

Calc::Calc(int n_type,char* n_exp) // Constructor
{

 type = n_type;
 expression = n_exp;

}

void Calc::Convert(int c_type)
{
 char* t_exp;
 t_exp = new char[MAX_CHAR]; // temporary expression initialize
 for(int i=0;i<MAX_CHAR;i++)
  t_exp[i]=NULL;

 int i=0,j=0;

 if(c_type == type) // do not need to convert
  return;
 
 if(c_type == INFIX) // convert POSTFIX to INFIX
 {
  stack<char> p;
  stack<char> t1,t2;
  while(expression[i]!=NULL)
  {
   if(expression[i] >= '0' && expression[i] <= '9') // is it operand?
   {
    p.push(expression[i]);
   }
   else if (expression[i]=='+'||expression[i]=='-'||expression[i]=='*'||expression[i]=='/'||expression[i]=='%') // is it operator?
   {
    do
    {
     if(p.top()==')')
      j++;
     if(p.top()=='(')
      j--;
     t2.push(p.top());
     p.pop();   
    }while(j);

    do
    {
     if(p.top()==')')
      j++;
     if(p.top()=='(')
      j--;
     t1.push(p.top());
     p.pop();   
    }while(j);

    p.push('(');
    while(!t1.empty())
    {
     p.push(t1.top());
     t1.pop();
    }
    p.push(expression[i]);
    while(!t2.empty())
    {
     p.push(t2.top());
     t2.pop();
    }
    p.push(')');

   }
   else if(expression[i] == ' ') // is it blank?
   {
   }
   else // unknown operator
   {
    throw "Error : Not allowed operator. (Calc::Convert(INFIX))";;
   }

   i++;


  }


  // load t_exp from stack p
  for(i=p.size()-1;!p.empty();i--)
  {
   t_exp[i] = p.top();
   p.pop();
  }



  //delete expression;
  expression = t_exp;
  type = INFIX;

  //cout << expression << endl;

  return ;

 }

 if(c_type == POSTFIX) // convert INFIX to POSTFIX
 {
  stack<char> t;
  while(expression[i]!=NULL)
  {
   if(expression[i] >= '0'&&expression[i] <='9') // is it operand?
   {
    t_exp[j] = expression[i];
    j++;
   }
   else if(expression[i] == '*'||expression[i] == '/'||expression[i] == '%') // higher priority operator
   {
    t.push(expression[i]);
   }
   else if(expression[i] == '+'||expression[i] == '-') // lower priority operator
   {
    while(!t.empty())
    {
     if(t.top()=='(')
      break;

     t_exp[j] = t.top();
     j++;
     t.pop();

     if(t_exp[j]=='+'||t_exp[j]=='-')
      break;
    }
    
    t.push(expression[i]);
   }
   else if(expression[i] == '(') // opened bracket
   {
    t.push(expression[i]);
   }
   else if(expression[i] == ')') // closed bracket
   {

    while(!t.empty())
    {
     if(t.top()=='(')
     {
      t.pop();
      break;
     }

     t_exp[j] = t.top();
     j++;
     t.pop();
    }
   }
   else if(expression[i] == ' ') // is it blank?
   {
   }
   else 
   {
    throw "Error : Not allowed operator. (Calc::void Convert(POSTFIX))";
   }

   i++;
  }

  while(!t.empty())
  {
   t_exp[j] = t.top();
   j++;
   t.pop();
  }


  //delete expression;
  expression = t_exp;
  type = POSTFIX;

  return;
 }

 throw "Error : There is an unknown type. (private:int type;void Calc::Convert(???))";

}

double Calc::Evaluate()
{
 if(type == INFIX)
 {
  this->Convert(POSTFIX);
  return this->Evaluate();
 }
 
 if(type == POSTFIX)
 { 
  int i=0;
  double answer,temp;
  stack<double> t;
  while(expression[i]!=NULL)
  {
   if(expression[i]>='0' && expression[i]<='9')
   {   
    t.push(expression[i]-'0');
   
   }
   else
   {
    temp = t.top();
    t.pop();
    switch(expression[i])
    {
    case '+':
     temp = t.top() + temp;
     break;
    case '-':
     temp = t.top() - temp;
     break;
    case '*':
     temp = t.top() * temp;
     break;
    case '/':
     temp = t.top() / temp;
     break;
    case '%':
     temp = static_cast<int>(t.top()) % static_cast<int>(temp);
     break;
    }
    //if(!t.empty())
     t.pop();

    t.push(temp);
   }

   i++;
  }

  answer = t.top();
  
 // this->Convert(INFIX);
 // cout << expression << " = "
 //  << answer << endl;
  
  return answer;
 }
 
  
 throw "Error : There is an unknown type. (private:int type;int Calc::Evaluate())";

 
}

char* Calc::PrintExp()
{
 return expression;
}