C++计算器的实现
能够实现+ - * / 与()的复合运算
功能简介
- 计算器的实现主要通过构建操作数栈和操作符栈
- 通过对操作符的判断来实现合理出入栈,来实现优先级
- 其中对栈的初始化,以及进栈出栈操作均为自己定义
- 支持负数,浮点数
- !!!!!运行()是确保输入法是
运行结果展示
代码头文件expr.h
expr.h
#pragma once// ExprCPro.cpp: 定义控制台应用程序的入口点。
//
#ifndef CIRCLE_H
#define CIRCLE_H
typedef struct StackNodeOPND //操作数栈
{
double value;
StackNodeOPND *next;
}*OPND;
typedef struct StackNodeOPTD //操作符栈
{
char op;
StackNodeOPTD *next;
}*OPTD;
int init(OPND&opnd); //操作数栈初始化
int init(OPTD&optr); //栈初始化
int push(OPND&opnd, const double value);//进栈操作
int push(OPTD&optd, const char op);
int pop(OPND&opnd, double &value);//出栈操作
int pop(OPTD&optd, char &op);
int getTop(OPND&opnd, double &value);//得到栈顶元素
int getTop(OPTD&optd, char &op);
int isEmpty(OPND &opnd);//判断栈是否为空
int isEmpty(OPTD &optd);
char precede(char a, char b);//优先级比较
double calc(double a, char theta, double b);//运算函数
double parse(char expr[]);//解析传入的字符串
#endif
对头文件定义函数的实现
expr.cpp
#include "stdafx.h"
#include "targetver.h"
#include<iostream>
#include <string>
#include <stack>
#include <string.h>
#include <cctype>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <vector>
#include "expr.h"
using namespace std;
int init(OPND&opnd) //栈初始化
{
while (opnd != NULL) { //删除栈
OPND temp = opnd;
opnd = temp->next;
free(temp);
}
opnd = NULL;
return 0;
}
int init(OPTD&optr) //栈初始化
{
while (optr != NULL) { //删除栈
OPTD temp = optr;
optr = temp->next;
free(temp);
}
optr = NULL;
return 0;
}
int push(OPND&opnd, const double value) { //添加栈指针
OPND temp = (OPND)malloc(sizeof(StackNodeOPND));
if (!temp) {
return -1;
}
temp->value = value;
temp->next = opnd;
opnd = temp;
return 0;
}
int push(OPTD&optd, const char op) { //添加栈指针
OPTD temp = (OPTD)malloc(sizeof(StackNodeOPTD));
if (!temp) {
return -1;
}
temp->op = op;
temp->next = optd;
optd = temp;
return 0;
}
int pop(OPND&opnd, double &value) {
if (opnd == NULL) {
return -1;
}
value = opnd->value;
OPND temp = opnd;
opnd = temp->next;
free(temp);
return 0;
}
int pop(OPTD&optd, char &op) {
if (optd == NULL) {
return -1;
}
op = optd->op;
OPTD temp = optd;
optd = temp->next;
free(temp);
return 0;
}
int getTop(OPND&opnd, double &value) {
if (opnd == NULL) {
return -1;
}
value = opnd->value;
return 0;
}
int getTop(OPTD&optd, char &op) {
if (optd == NULL) {
return -1;
}
op = optd->op;
return 0;
}
int isEmpty(OPND &opnd) {
if (opnd == NULL) {
return 1;
}
else {
return 0;
}
}
int isEmpty(OPTD &optd) {
if (optd == NULL) {
return 1;
}
else {
return 0;
}
}
char precede(char a, char b) {
char aPriorTable[6][6] = {
//+ - * / ( )
{ '>','>','<','<','<','>' },
{ '>','>','<','<','<','>' },
{ '>','>','>','>','<','>' },
{ '>','>','>','>','<','>' },
{ '<','<','<','<','<','=' },
{ '>','>','>','>','>','>' }
};
int x = -1;
int y = -1;
//
if (a == 0) {
return '<';
}
char opr[] = "+-*/()";
if (b == '+')y = 0;
if (b == '-')y = 1;
if (b == '*')y = 2;
if (b == '/')y = 3;
if (b == '(')y = 4;
if (b == ')')y = 5;
if (a == '+')x = 0;
if (a == '-')x = 1;
if (a == '*')x = 2;
if (a == '/')x = 3;
if (a == '(')x = 4;
if (a == ')')x = 5;
return aPriorTable[x][y];
//for (int i = 0; i < 6; i++) {
// if (a == opr[i])x = i;
// printf("\n x is%d", x);
// if (b == opr[i])y = i;
// if (b == '-')y = 1;
// printf("\n y is%d", y);
// printf("\naPriorTable[x][y]is %c", aPriorTable[x][y]);
// return aPriorTable[x][y];
//}
}
double calc(double a, char theta, double b) {
double value = 0;
switch (theta) {
case'+':value = a + b; break;
case'-':value = a - b; break;
case'*':value = a * b; break;
case'/':value = a / b; break;
default: {
exit(0);
}
}
return value;
}
double parse(char expr[]) {
OPND opnd = NULL;
OPTD optr = NULL;
init(opnd);
init(optr);
for (int i = 0; expr[i] != '\0'; i++) {
char c = expr[i];
if (c >= '0'&&c <= '9' || c == '.') {
char token[20] = { 0 };
int j = 0;
while (expr[i + j] >= '0'&&expr[i + j] <= '9' || expr[i + j] == '.') {
// printf("this is %c", expr[i + j]);
token[j] = expr[i+j];//error
j++;
}
token[j] = '\0';
i = i + j - 1;
double value = atof(token);
//printf("value is %f", value);
push(opnd, value);
}
else {
char op = 0;
getTop(optr, op);//b is op optr is a
switch (precede(op, c)) {
case '<':push(optr, c);
break;
case'=':
//printf("%c", op);
pop(optr, op);
break;
case'>':
double a = 0;
double b = 0;
pop(opnd, b);
pop(opnd, a);
pop(optr, op);
push(opnd, calc(a, op, b));
i--;
break;
}
}
}
while (!isEmpty(optr)) {
double a = 0;
double b = 0;
char op = 0;
pop(opnd, b);
pop(opnd, a);
pop(optr, op);
push(opnd, calc(a, op, b));
}
double value = 0;
pop(opnd, value);
return value;
}
Main函数
main.cpp
// ConsoleApplication3.cpp: 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include<iostream>
#include "expr.h"
int main()
{
using namespace std;
char str1[20];
cout << "支持四则运算与优先级+-*/" << endl;
cout << "edg 5+(3-1)" << endl;
cin.get(str1, 20);
double b = parse(str1);
printf("the result is %0.3f", b);
getchar();
getchar();
return 0;
return 0;
}