VC++.NET中用类实现带科学计数法的四则运算计算器(有完整的代码哦)(2005-05-08)...

带科学计数法的有括号四则运算计算器今天交差了,除了输入验证外,基本和需求吻合
代码不多,但是功能还算强大
这里面有我两个得意之处
一是对e的处理, 我把它当成了一个运算符,哈哈,这是个灵感
二是对负号的处理,“-”既可以当作减号也可以当作负号,用个判断就可以了
好了,不多说,看代码吧,开发环境是VC++.NET



// Calculator.h : 头文件
//
#ifndef CALCULATOR_H_2005_04_27__
#define CALCULATOR_H_2005_04_27__


#include <stack>

using namespace std;

typedef stack<double> STACK_DOUBLE;
typedef stack<char> STACK_CHAR;

class CCalculator
{
 public :
  double CountResult(CString csExp);
  int CheckString(CString csExp);
  int ReturnError(CString csExp);
  CCalculator(void);

 private:
  STACK_DOUBLE m_doubleStack;  //操作数栈
  STACK_CHAR m_charStack;  //操作符号栈
  static char m_priTable[8][8]; //运算符优先级列表

  char QueryPri(char chOperator1,char chOperator2); 
   //查找运算符优先级

  //int JudgeOperator(char ch);
  // //判断是否为操作符号

  int JudgeOperator(CString csExp, int iLocation);
   //判断是否为操作符号

  double Count(double dbNum1,double dbNum2, char chOper);
         //四则运算函数,返回计算结果

  double GetCurrentDouble(CString csExpression,int& iCurrentLocation);
   //从表达式的当前位置查找操作数并返回,当前位置向前移动

  
};

#endif



//Calculator.cpp

#include "stdafx.h"
#include "Calculator.h"
#include <stack>
#include <math.h>

using namespace std;

//检查表达式是否合法
int CCalculator::CheckString(CString csExp )
{
 
 return 1;
 
};

//计算合法表达式的值
double CCalculator::CountResult(CString csExp)
{  
 int i = 0;
 int j = 0;
 int iLength = 0;
 int& alia_i = i;
 char chMyOperator = '\0';
 char chCompareResult = '\0';
 char chCurrent = '\0';
 char chTop = '\0';
 double dbNumber1 = 0.0;
 double dbNumber2 = 0.0;
 double dbResult = 0.0;
 double dbCurrentNumber = 0.0;
 
 csExp += "#";
 iLength = csExp.GetLength();  //获取表达式的长度
 m_charStack.push('#');  

 for (i=0; i<=iLength; )
 { 
  chCurrent = csExp[i];

  if ( JudgeOperator(csExp,i) ) //如果为操作符
  { 
   //比较当前操作符与栈顶操作符的优先级
   chTop = m_charStack.top();
   chCompareResult = QueryPri(chCurrent, chTop);
    

   switch (chCompareResult)
   //根据比较结果执行不同的操作
   {
    case '>' :
     //当前操作符优先级较高,压入操作符号栈
     m_charStack.push(chCurrent);
     i++;
     break;

    case '<' :
     //当前操作符优先级较小,计算前面的运算结果
     chMyOperator = m_charStack.top();
     m_charStack.pop();
     dbNumber2 = m_doubleStack.top();
     m_doubleStack.pop();
     dbNumber1 = m_doubleStack.top();
     m_doubleStack.pop();
     dbResult = Count(dbNumber1, dbNumber2, chMyOperator);
     m_doubleStack.push(dbResult);
     break;

    case '=' :
     //当前操作符与栈顶操作符优先级相同,有两种可能
                   
     if (chCurrent==')')
     //如果为左右括号相遇,脱括号
     {
      m_charStack.pop();
      i++;
      break;
     }//end if
     else
     //如果为两个'#'相遇,运算结束
     {
      if (chCurrent=='#')
      { 
       dbResult = m_doubleStack.top();
       return dbResult;
       break;
      }//end if

     }//end else
   
    case 'E' :
     //比较出错
     break;
     
    default:
     break;

   }//end switch
   
  
  }//end if
  else
  {
   dbCurrentNumber = GetCurrentDouble(csExp,alia_i);
   m_doubleStack.push(dbCurrentNumber);

  }//end else
   
 }//end for


 return dbResult;
 
 

};


//对不合法的表达式,找到错误,通知用户修改
int CCalculator::ReturnError(CString csExp)

 return 1;

};

//查找运算符优先级
char CCalculator::QueryPri (char chOperator1, char chOperator2)

 int i = 0;
 int j = 0;

 switch (chOperator1)
 {
  case '+':
   i = 0;
   break;
  case '-':
   i = 1;
   break;
  case '*':
   i = 2;
   break;
  case '/':
   i = 3;
   break;
  case '(':
   i = 4;
   break;
  case ')':
   i = 5;
   break;
  case '#':
   i = 6;
   break;
  case 'e':
   i = 7;
   break;
  default:
   break;
 };

 switch (chOperator2)
 {
  case '+':
   j = 0;
   break;
  case '-':
   j = 1;
   break;
  case '*':
   j = 2;
   break;
  case '/':
   j = 3;
   break;
  case '(':
   j = 4;
   break;
  case ')':
   j = 5;
   break;
  case '#':
   j = 6;
   break;
  case  'e':
   j = 7;
   break;
  default:
   break;
 };

 return m_priTable[i][j];
};

//初始化运算符优先级列表
char CCalculator::m_priTable[8][8] =

 //+,,,-,,,*,,,/,,,(,,,),,,#,,,e,
 {'<','<','<','<','>','E','>','<'},  //+
 {'<','<','<','<','>','E','>','<'}, //-
 {'>','>','<','<','>','E','>','<'}, //*
 {'>','>','<','<','>','E','>','<'}, ///
 {'>','>','>','>','>','E','>','E'}, //(
 {'<','<','<','<','=','E','E','<'}, //)
 {'<','<','<','<','<','<','=','<'}, //#
 {'>','>','>','>','>','E','>','E'}   //e


 
};

//构造函数
CCalculator::CCalculator(void)

 int i = 0;

 stack<double>::size_type double_Length;
 stack<char>::size_type char_Length;


 if (!(m_doubleStack.empty()))
 //初始化操作数栈
 { 
  double_Length = m_doubleStack.size();

  for (i=1; i<=double_Length; i++)
  {
   m_doubleStack.pop();
  }//end for
 }//end if

 
 if (!(m_charStack.empty()))
 //初始化操作符号栈
 { 
  char_Length=m_charStack.size();

  for ( i=1; i<=char_Length; i++)
  {
   m_charStack.pop();
  }//end for
   
 }//end if
 
};


//判断是否为运算符
int CCalculator::JudgeOperator(CString csExp, int iLocation)
{
 switch (csExp[iLocation])
 {
 case '+':
  return 1;
  break;
 case '-':
  if (iLocation==0)
  {
   return 0;
   break;
  }
  else
  { if ((csExp[iLocation-1]=='(') || (csExp[iLocation-1]=='e'))
   {
    return 0;
    break;
   }
   else
   {
    return 1;
    break;
   }
  }
  return 1;
  break;
 case '*':
  return 1;
  break;
 case '/':
  return 1;
  break;
 case '(':
  return 1;
  break;
 case ')':
  return 1;
  break;
 case '#':
  return 1;
  break;
 case 'e':
  return 1;
  break;
 default :
  return 0;
  break;

 };
};

//四则运算函数,返回结果
double CCalculator::Count(double dbNum1,  double dbNum2, char chOper)
{
 double dbResult = 0.0;

 switch (chOper)
 {
  case '+':
   dbResult = dbNum1 + dbNum2;
   break;

  case '-':
   dbResult = dbNum1 - dbNum2;
            break;

  case '*':
   dbResult = dbNum1 * dbNum2;
   break;

  case '/':
   if (!(fabs(dbNum2 - 0.0) < 1e-6 ))
   {
    dbResult = dbNum1 / dbNum2;

   }
   break;
  
  case 'e':
   dbResult = dbNum1 *  pow(10.0,dbNum2);
   break;

  default:
   break;
 };

 return dbResult;
 
};

//从表达式的当前位置查找操作数并返回,当前位置向前移动
double CCalculator::GetCurrentDouble(CString csExpression,int& iCurrentLocation)
{
 int i = 0;
 int j = 0;
 int iExpressionLength = 0;
 int iELocation = 0;
 CString csDoubleString("");
 char chCurrentChar = '\0';
 double dbNumber = 0.0;
    i = iCurrentLocation;
 
 iExpressionLength = csExpression.GetLength();
 
 for ( j=i+1; j<iExpressionLength; )
 { 
  chCurrentChar = csExpression[j];

  if (!JudgeOperator(csExpression,j))
  {
   j++;

  }//end if
  else
  { 
  
   break;

   
  }//end else
 
 }//end for

 csDoubleString = csExpression.Mid(i, j-i);
 
 dbNumber = atof(csDoubleString);

 
 
 iCurrentLocation = j;

 return dbNumber;


};

















亲爱的朋友,阅读完本贴之后,请不要吝啬您的留言,无论赞扬或是批评,我都会深深地感谢您!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值