"sharing happiness is happy"
2021-10-8
一.细节处理:
1.注意负数 因此要进行字符串预处理
string format(string str)
{
int len = str.length();
for (int i = 0; i < len; i++)
{
if (str[i] == '-')
{
if (i == 0) { str.insert(0, 1, '0'); }//处理-3*2+1情况
else if (str[i - 1]=='(') { str.insert(i, 1, '0'); }//处理(-3*4+1)情况
}
}
return str;
}
2.考虑除数为0
case '/':
if (0 != y) { res = x / y; }
else { cout << "非法表达式"; return -1; }
break;
3.原字符串再加上一个定界符 '#'
str=str+'#'
4.优先级: 1."("未入栈前为3 入栈后为0 2.”)" 为0 3.”+" "-"为1 4.”*"和"/"为2 5."#"为-1
二.知识要点:
中缀表达式转为后缀表达式
1. 首先设置存储运算符和存储操作数两个栈 即Symbol[N]和Num[N]且分别对应top2,top1
top1=-1 Symbol[0]='#' //运算符栈设置定界符 top2=0
2.入栈和出栈的规则 字符串为str
一.若str[i]>='0&&str[i]<='9',则入操作数栈并继续扫描以一个字符
二.否则 将当前字符str1与运算符栈的栈顶元素str2进行优先级比较 ,自写比较函数
1. 此时若str1优先级大于str2 则将str1入运算符栈并继续扫描下一个字符
2.否则弹出运算符栈的栈顶元素和弹出操作数栈的两个元素进行运算,并继续执行当前字符
3其中'#'和运算符栈中的'#'相遇 则弹出栈中的'#' ”)“右括号遇到运算符栈中的左括号”(” 弹出栈中的"("
三.最后 return Num[top1]
三.完整源码:
#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;
class Expression
{
public:
Expression(string str);
~Expression();
int Compute();
private:
int Comp(char str1, char str2);
string str1;
};
Expression::Expression(string str)
{
this->str1 = str + '#';//以定界符开头
}
Expression :: ~Expression() {}
//将中缀表达转为后缀表达
int Expression::Compute()
{
int Num[100], Symbol[100];//定义存操作数和运算符的两个栈
int i, k, x, y, res;
char op;
Symbol[0] = '#';
int top1 = -1, top2 = 0;
for (i = 0; str1[i] != '\0';)
{
if (str1[i] >= '0' && str1[i] <= '9') { Num[++top1] = str1[i++] - '0'; }
else {//非操作数就比较运算符优先级
int cmp = Comp(str1[i], Symbol[top2]);
if (cmp == 1) { Symbol[++top2] = str1[i++]; }//将运算符入栈 并接着扫描下一个字符
else if (cmp == 0) { --top2; i++; }//优先级相等 弹栈 并接着扫描下一个字符
else {//优先级低 继续处理当前运算符
y = Num[top1--];//后面的数要先弹出来 才不会算反
x= Num[top1--];
op = Symbol[top2--];
switch (op)
{
case '+':
res = x + y;//将运算结果入栈
break;
case '-':
res = x - y;
break;
case '*':
res = x * y;
break;
case '/':
if (0 != y) { res = x / y; }
else { cout << "非法表达式"; return -1; }
break;
default:break;
}
Num[++top1] = res;
}
}
}
return Num[top1];
}
string format(string str)
{
int len = str.length();
for (int i = 0; i < len; i++)
{
if (str[i] == '-')
{
if (i == 0) { str.insert(0, 1, '0'); }//处理-3*2+1情况
else if (str[i - 1]=='(') { str.insert(i, 1, '0'); }//处理(-3*4+1)情况
}
}
return str;
}
int main()
{
string str;
int n = 3;
while (n--)
{
cout << "请输入一个表达式: " << endl;
cin >> str;
str = format(str);
Expression E(str);
int result = E.Compute();
cout << "表达式的值的是: " << result << endl;
}
return 0;
}
int Expression::Comp(char str1, char str2)//当前字符元素和栈顶运算符优先级比较
{
//1代表 str1优先级大于str2 0 代表相等 -1代表小于
switch (str1)
{
case'+':case'-':
if (str2 == '#'||str2==')'||str2=='(') { return 1; }//左括号入队列后优先级变为0
else { return -1; }
break;
case'*':case'/':
if (str2 == '*' || str2 == '/') { return -1; }
else { return 1; }
break;
case'(':
return 1;
break;
case')':
if (str2 == '(') { return 0; }
else if(str2 == '#') { return 1; }
else { return -1; }
break;
case'#':
if (str2 == '#') { return 0; }
else { return -1; }
break;
default: break;
}
}
四.测试结果:
五. 热爱编程 热爱计算机~
附:java版实现
import java.io.IOException;
import java.sql.Date;
import java.text.SimpleDateFormat;
import java.util.Scanner;
class Expression
{
private String str;
public Expression(String s)
{
this.str=s+"#";
}
private int Comp(char str1,char str2)
{
switch(str1)
{
case'+':
case'-':
if(str2=='#'||str2=='('||str2==')') {return 1;}
else {return -1;}
case'*':
case'/':
if(str2=='*'||str2=='/') {return -1; }
else {return 1;}
case'(':
return 1;
case')':
if(str2=='(') {return 0;}
else if(str2=='#') {return 1;}
else {return -1;}
case '#':
if(str2=='#') {return 0;}
else {return -1;}
default:
return 0;
}
}
public int Compute() throws IOException
{
int Num[]=new int[100];
char Symbol[]=new char[100];
int top1=-1,top2=0;
Symbol[0]='#';
int j=0;
char op;
while(j<this.str.length())
{
if(str.charAt(j)>='0'&&str.charAt(j)<='9') {Num[++top1]=str.charAt(j++)-'0';;}
else {
//运算符
int result=0;
int cmp=Comp(str.charAt(j),Symbol[top2]);
if(cmp==1){Symbol[++top2]=str.charAt(j++);}
else if(cmp==0) {j++;--top2;}//运算符出栈 继续处理下一个字符
else if(cmp==-1) {
int y=Num[top1--];
int x=Num[top1--];
op=Symbol[top2--];
switch(op)
{
case'+':
result=x+y;
break;
case'-':
result=x-y;
break;
case'*':
result=x*y;
break;
case'/':
if(0!=y) {result=x/y;}
else {throw new IOException("除数为0!");}
break;
default:break;
}
Num[++top1]=result;
}
}
}
return Num[top1];
}
}
public class Tencent
{
static void Format(StringBuilder s)
{
int len=s.length();
for(int i=0;i<len;i++)
{
if(s.charAt(i)=='-')
{
if(i==0) {s.insert(0, '0');}
else if(s.charAt(i-1)=='(') {s.insert(i,'0' );}
}
}
}
static public void main(String []args) throws IOException
{
StringBuilder s=new StringBuilder("(2+3)*2+1");
Format(s);
Expression str=new Expression(s.toString());
System.out.println(str.Compute());
}
}