语言 C++
工具
- stack
- map
步骤
- 初始化
- 读取字符串
- 去空格
- 负号处理
- 判断为空
- 检查格式
- 计算
示例![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/df04c04074ab1e1f2856a388229641f5.png)
代码
#include <iostream>
#include <string>
#include <stdio.h>
#include <stack>
#include <map>
#include <math.h>
#include <stdlib.h>
#include <sstream>
using namespace std;
char op[8][8];
map<char, int> m;
void init()
{
m['+'] = 1, m['-'] = 2, m['*'] = 3, m['/'] = 4, m['('] = 5, m[')'] = 6, m['#'] = 7;
op[1][1] = '>', op[1][2] = '>', op[1][3] = '<', op[1][4] = '<', op[1][5] = '<', op[1][6] = '>', op[1][7] = '>';
op[2][1] = '>', op[2][2] = '>', op[2][3] = '<', op[2][4] = '<', op[2][5] = '<', op[2][6] = '>', op[2][7] = '>';
op[3][1] = '>', op[3][2] = '>', op[3][3] = '>', op[3][4] = '>', op[3][5] = '<', op[3][6] = '>', op[2][7] = '>';
op[4][1] = '>', op[4][2] = '>', op[4][3] = '>', op[4][4] = '>', op[4][5] = '<', op[4][6] = '>', op[2][7] = '>';
op[5][1] = '<', op[5][2] = '<', op[5][3] = '<', op[5][4] = '<', op[5][5] = '<', op[5][6] = '=';
op[6][1] = '>', op[6][2] = '>', op[6][3] = '>', op[6][4] = '>', op[6][6] = '>', op[6][7] = '>';
op[7][1] = '<', op[7][2] = '<', op[7][3] = '<', op[7][4] = '<', op[7][5] = '<', op[7][7] = '=';
}
double operate(double num1, char oper, double num2)
{
if(oper == '+')
return num1 + num2;
if(oper == '-')
return num1 - num2;
if(oper == '*')
return num1 * num2;
if(oper == '/')
return num1 / num2;
}
string trim(string str)
{
int index = 0;
if( !str.empty())
{
while( (index = str.find(' ',index)) != string::npos)
{
str.erase(index,1);
}
}
return str;
}
string change(string str)
{
int start;
str+="#";
for(int i = 0; i < str.length(); i++){
if(str[i] == '-'){
if(i == 0 || i != 0 && (m[str[i-1]] >= 1 && m[str[i-1]] <= 5)
&& str[i+1] >= '0' && str[i+1] <= '9'){
str += " ";
int j = i+1;
start = j;
while(m[str[j]] == 0)
j++;
string s = str.substr(start, j-start);
for(int k = str.length() - 1; k >= j; k--)
str[k] = str[k-3];
str[i] = '(', str [i+1] = '0', str[i+2] = '-';
int l = i+3;
for(int k = 0; k < s.length(); k++){
str[l+k] = s[k];
}
str[l+s.length()] = ')';
}
}
}
str.erase(str.length()-1, 1);
return str;
}
bool test(string str)
{
bool flag = true;
int ifNum = 0;
stack<char> s;
int start, e;
str += "#";
for(int i = 0; i < str.length(); i++){
//判断非法字符
if((str[i] < '0' || str[i] > '9') && m[str[i]] == 0 && str[i] != '.') return false;
if(str[i] == '#' && i != str.length() - 1) return false;
//判断小数点
if(m[str[i]] == 0){
if(ifNum == 0){
start = i;
ifNum = 1;
}
}
if(m[str[i]] != 0){
if(ifNum == 1){
e = i;
string s1 = str.substr(start, e - start);
int pointNum = 0;
if(s1[0] == '.') return false;
for(int j = 0; j < s1.length(); j++){
if(s1[j] == '.')
pointNum++;
}
if(pointNum > 1)
return false;
}
ifNum = 0;
}
//判断符号
if(str[i] == '+' || str[i] == '-' || str[i] == '*' || str[i] == '/'){
if(i == 0) return false;
if((str[i-1] < '0' || str[i-1] > '9') && str[i-1] != ')') return false;
if((str[i+1] < '0' || str[i+1] > '9') && str[i+1] != '(') return false;
}
//判断括号
if(str[i] == '(') s.push(str[i]);
if(str[i] == ')'){
if(s.empty()) return false;
char c = s.top();
if(c == '(')
s.pop();
else
return false;
}
}
//判断括号
if(s.empty() == false)
flag = false;
return flag;
}
void caculate(string str)
{
str+="#";
int flag = 0;
int start, e;
stack<double> numStack;
stack<char> operStack;
operStack.push('#');
int index = 0;
while(str[index] != '#' || operStack.top() != '#'){
if(m[str[index]] == 0){
if(flag == 0){
start = index;
flag = 1;
}
index++;
}
else if(m[str[index]] != 0){
if(flag == 1){
e = index;
stringstream s (str.substr(start, e-start));
double num;
s >> num;
numStack.push(num);
flag = 0;
}
char c = operStack.top();
if(op[m[c]][m[str[index]]] == '<'){
operStack.push(str[index]);
index++;
}else if(op[m[c]][m[str[index]]] == '='){
operStack.pop();
index++;
}else{
char oper = operStack.top();
operStack.pop();
double num1 = numStack.top();
numStack.pop();
double num2 = numStack.top();
numStack.pop();
//printf("%f***%c***%f",num2,oper,num2);
double result = operate(num2, oper ,num1);
numStack.push(result);
}
}
}
printf("\t\t\t= %f\n",numStack.top());
}
int main()
{
init();
printf("\n\n\n\t\t\t请输入表达式,退出请输入end:\n");
string s;
while(1){
printf("\n\t\t\t");
string s;
//cin >> noskipws >> s;
getline(cin, s, '\n');
s = trim(s); //去除空格
s = change(s); //处理负数
//cout << s;
if(s == "end"){
break;
}
else if(s.length() > 0){ //判断不为空
if(!test(s))//检测格式
printf("\t\t\t格式错误\n");
else
caculate(s); //计算
}
else{
printf("\t\t\t输入不能为空\n");
}
}
return 0;
}
有什么错误或者疑问请下方留言或加微信g1807069286