MFC使用双栈实现简单计算器

来源:互联网 发布:php json转数组 编辑:程序博客网 时间:2024/05/22 15:52

//2013.5.24

//数据结构,中石大,cakeman

//使用操作数栈和操作符栈,计算表达式的值

//运行界面

源文件下载地址:http://download.csdn.net/detail/ye_xingren/5468657

 

 

关键代码:

void CCalculaterDlg::OnCal()
{

 // TODO: Add your control notification handler code here
 CString StrErr;//提示错误
 bool m_Legal=false;
 if(m_exp.IsEmpty())
 {
  StrErr="请输入表达式!";
  MessageBox(StrErr);
  return;
 }
 char op='#';
 
 
 op=m_exp.GetAt(0);//m_exp为表达式字符串
 if (!IsOperand(op))//判操作数否
 {
  switch(op)
  {
  case '(':
  case '-':
   break;
  default:
   {
    StrErr="不能以不合法运算符开头(包括‘+’)";
    MessageBox(StrErr);
    m_exp="";
    SetDlgItemText(IDC_EXP,m_exp);
    return;
   }
  }
 }
 op=m_exp.GetAt(m_exp.GetLength()-1);
 if (!IsOperand(op))
 {
  switch(op)   
  {   
  case ')':   
   break;   
  default:   
   {    
    StrErr="不能以运算符结尾!";
    MessageBox(StrErr);
    m_exp="";
    SetDlgItemText(IDC_EXP,m_exp);
    return;    
   }                              
  }
 }
 for (int i=0;i<m_exp.GetLength()-1;i++)
 {
  op=m_exp.GetAt(i);
  char cp;
  if (cp=m_exp.GetAt(i),m_exp.GetLength()==1&&isp(cp)>=0&&icp(cp)>=0)
  {
   StrErr="仅运算符无法计算!";
   MessageBox(StrErr);
   m_exp="";
   SetDlgItemText(IDC_EXP,m_exp);
   return;
  }
  else  if (isp(op)>0&&isp(op)<6&&icp(op)>0&&icp(op)<6)
  {
   if (cp=m_exp.GetAt(i+1),isp(cp)>0&&isp(cp)<6&&icp(cp)>0&&icp(cp)<6)
   {
    StrErr="两运算符间无运算数,请检查表达式!";
    MessageBox(StrErr);
    m_exp="";
    SetDlgItemText(IDC_EXP,m_exp);
    return;
   }
  }
  m_Legal=true;
  
 }
 if(m_Legal)
 Calculate(m_exp);
}

 

void CCalculaterDlg::Calculate(CString exp)
{
 stack<char> s;
 char op='#',ch='#';//ch当前到来字符,op操作符栈顶元素 
 stack<char> optr;//操作符栈 
 optr.push(op);
 
 stack<double> opnd;//操作数栈 
 double  opndTop=0.0,opndTop2=0.0;
 char optrTop;//栈顶元素
 int left=0,right=0;//左右括弧个数

 exp+="#";
 //optrTop=optr.top();
 //AfxMessageBox(optrTop);

 int i=0,j=0;//计数器

 for (i=0,op=exp.GetAt(i);i<exp.GetLength();i++)//扫描表达式检查匹配括号
 {
  op=exp.GetAt(i);
  if(isp(op)==1&&icp(op)==6)
   left++;
  if(isp(op)==6&&icp(op)==1)
   right++; 
 }
 if(left!=right)
 {
  MessageBox("括号不匹配!请检查表达式");
  m_exp="";
  SetDlgItemText(IDC_EXP,m_exp);
  return;
 }
 /*for (int i=0,op=exp.GetAt(i);i<exp.GetLength();i++)
 {
  if (isp(op)==-1)
  {
   opnd.push(int(op-'0'));
   if ()
   {
   }
  }
 }*/
 CString opndStr;
 double opndNum;
 
 i=0;
 ch=exp.GetAt(i);

 while (optr.empty()==false)
 {
  ch=exp.GetAt(i);
  if (IsOperand(ch))
  {    
   for(j=i;j<exp.GetLength();j++)
   {
    if (!IsOperand(exp.GetAt(j)))
     break;
   }
   opndStr=exp.Mid(i,j-i);
   opndNum=atof(opndStr);
   opnd.push(opndNum);//转换为操作数后压入栈中

   i=j;//从j元素处开始检测
  }
  else
  {
   optrTop=optr.top();//取操作符栈顶元素
   if (isp(optrTop)<icp(ch))//新读入操作符优先级高
   {
    optr.push(ch);
    i++;
   }
   else if (isp(optrTop)>icp(ch))//新读入操作符优先级低
   {
    op=optr.top();
    optr.pop();
    opndTop=opnd.top();
    opnd.pop();
    opndTop2=opnd.top();
    opnd.pop();
    opnd.push(GetResult(opndTop2,opndTop,op));
   }
   else{
    op=optr.top();
    optr.pop();
    if(op=='(')
     i++;
   }
  }
 }
 //dlg.SetDlgItemText(IDC_EDIT_Res,)
 //Result dlg;
 CString res;
 res.Format(_T("%lf"),opnd.top());
 //dlg.DoModal();
 SetDlgItemText(IDC_Result,res);
 
 
}

bool CCalculaterDlg::IsOperand(char ch)
{
 if ((ch>='0'&&ch<='9')||ch=='.')
 {
  return true;
 }
 else return false;
}

int CCalculaterDlg::isp(char ch)
{
 switch(ch)
 {
 case '#':
  return 0;
  break;
 case '(':
  return 1;
  break;
 case '*':
  return 5;
  break;
 case '/':
  return 5;
  break;
 case '%':
  return 5;
  break;
 case '+':
  return 3;
  break;
 case '-':
  return 3;
  break;
 case ')':
  return 6;
  break;
 default:
  return -1;
 }

}

int CCalculaterDlg::icp(char ch)
{
 switch(ch)
 {
 case '#':
  return 0;
  break;
 case '(':
  return 6;
  break;
 case '*':
  return 4;
  break;
 case '/':
  return 4;
  break;
 case '%':
  return 4;
  break;
 case '+':
  return 2;
  break;
 case '-':
  return 2;
  break;
 case ')':
  return 1;
  break;
 default:
  return -1;
 }
}

double CCalculaterDlg::GetResult(double a, double b, char c)
{
 switch (c)
 {
 case '*':
  return a*b;
  break;
 case '/':
  return a/b;
  break;
 case '+':
  return a+b;
  break;
 case '-':
  return a-b;
  break;
 default:
  exit(-1);//Error
 }
}

 

原创粉丝点击