计算器的实现

来源:互联网 发布:执法记录仪删除数据 编辑:程序博客网 时间:2024/04/28 06:21
闲着无聊,写个小程序.总共两个函数,有个有点小长,不过也懒得重新封装了,也没有面向对象.注释比较详细,希望大家能看懂.
    计算表达式长度限制在128位以内,支持浮点运算

#include
#include
#include
#include

using namespace std;

float caculOnce(float left, char op, float right){
  switch(op){
      case '+':
          return left + right;
      case '-':
          return left - right;
      case '*':
          return left * right;
      case '/':
          return left / right;
  }
}

float caculAll(char *testCase){
  int len = strlen(testCase);
  float left, right, temp;//存放三个数据
  left = right = temp = 0.0;
  int r = 0;//存放结果
  bool isLeft = true;//判断是否在读取左操作数
  bool inParentheses = false;//是否在括号里
  int parentheseCount = 0;//碰到的左括号个数
  bool hasTemp, hasLeft, hasRight;
  hasTemp = hasLeft = hasRight = false;
  char stack[64];//存放括号里的内容,长度不超过20个字符
  char op1 = '0',op2 = '0';//存放两个操作符
  int j = 0;//标记指向stack的指针的位置
  for (int i = 0; i < len; i++){
      if(inParentheses){//在括号中
          if(testCase[i] == '('){//是左括号
              parentheseCount++;
              stack[j++] = testCase[i];
          }else if(testCase[i] == ')'){//是右括号
                if(parentheseCount == 1){//左括号数为1
                  stack[j] = '\0';
                  right = caculAll(stack);//递归运算
                  inParentheses = false;
                  parentheseCount = j = 0;
              }else{//左括号数大于1
                  parentheseCount --;//自减
                  stack[j++] = testCase[i];
              }
          }else{//不是括号
              stack[j++] = testCase[i];//存储当前字符到stack中
          }
      }else if(testCase[i] >= '0' && testCase[i] <= '9'){//是数字
          if(isLeft){//判断是否在操作左操作数
              if(!hasLeft)
                  left = atof(&testCase[i]);//是,则把新数字接在左操作数尾部
              hasLeft = true;
          }else{//不是,则把新数字接在右操作数尾部
              if(!hasRight)
                  right = atof(&testCase[i]);
              hasRight = true;
          }
      }else{//不是数字
          switch(testCase[i]){//判断当前符号是什么
              case '*'://乘号
              case '/'://除号
                  if(op2 == '0'){//cout<<"op2 为空"<<endl;
                       if(op1 == '0'){//cout<<"op1 为空"<<endl;
                         op1 = testCase[i];
                     }else{//cout<<"op1非空"<<endl;
                         if(op1 == '*' || op1 == '/'){//cout<<"op1为乘除"<<endl;
                             left  = caculOnce(left, op1, right);
                             right = 0;
                             hasRight = false;
                             op1 = testCase[i];
                         }else{//cout<<"op1为加减"<<endl;
                             op2 = testCase[i];
                             temp = left;
                             left = right;
                             right = 0;
                             hasRight = false;
                             isLeft = false;
                         }
                     }
                  }else{//op2非空
                     if(op2 == '*' || op2 == '/'){//op2为乘除
                         if(op1 == '*' || op1 == '/'){//op1为乘除
                             left = caculOnce(temp, op1, left);
                             left = caculOnce(left, op2, right);
                             right = temp = 0;
                             hasTemp = hasRight = false;
                             op2 = '0';                           
                             op1 = testCase[i];
                         }else{//op1为加减
                             left = caculOnce(left, op2, right);
                             right = 0;
                             op2 = testCase[i];
                             hasRight = false;
                         }
                     }else{//op2为加减
                         left = caculOnce(temp, op1, left);
                         op1 = op2; op2 = '0';
                         temp = left; hasTemp = true;
                         left = right;
                         right = 0; hasRight = false;
                     }
                  }
                  isLeft = false;
                  break;
              case '+'://加号
              case '-'://减号
                  if(op2 == '0'){//cout<<"op2 为空"<<endl;
                       if(op1 == '0'){//cout<<"op1 为空"<<endl;
                         op1 = testCase[i];
                     }else{//cout<<"op1非空"<<endl;
                         left  = caculOnce(left, op1, right);
                         right = 0;
                         hasRight = false;
                         op1 = testCase[i];
                     }
                  }else{//op2非空
                     if(op2 == '*' || op2 == '/'){//op2为乘除
                         if(op1 == '*' || op1 == '/'){//op1为乘除
                             left = caculOnce(temp, op1, left);
                             left = caculOnce(left, op2, right);
                         }else{
                             left = caculOnce(left, op2, right);
                             left = caculOnce(temp, op1, left);
                         }
                         right = temp = 0;
                         op2 = '0';
                         hasTemp = hasRight = false;
                         op1 = testCase[i];
                     }else{//op2为加减
                         left = caculOnce(temp, op1, left);
                         op1 = op2; op2 = '0';
                         temp = left; hasTemp = true;
                         left = right;
                         right = 0; hasRight = false;
                     }
                  }
                  isLeft = false;
                  break;
              case '('://是左括号
                  parentheseCount++;//左括号数自增
                  inParentheses = true;
                  break;
              default:
                  cout<<"invalid input!!!"<<endl;
                  exit(0);
          }
      }
      if(i == len - 1){//最后一个字符
          if(op1 != '0' && op2 != '0'){
              if(op2 == '*' || op2 == '/'){//op2为乘除
                  if(op1 == '*' || op1 == '/'){//op1为乘除
                     left = caculOnce(temp, op1, left);
                     left = caculOnce(left, op2, right);
                  }else{//op1为加减
                     left = caculOnce(left, op2, right);
                     left = caculOnce(temp, op1, left);
                  }
              }else{//op2为加减
                  left = caculOnce(temp, op1, left);
                  left = caculOnce(left, op2, right);
              }
          }else if(op1 != '0'){
              left = caculOnce(left, op1, right);
         
          cout << testCase << " = " << left << endl;//打印表达式与结果
          return left;
      }
  }
}

int main(int argc, char *argv[]){
  char ex[128];
  if(argc > 1){
      strcpy(ex, argv[1]);
  }else{
      cout << "输入计算式:";
      cin >> ex;
  }
  cout << "the result is " << caculAll(ex) << endl;
  return 0;
}
0 0