++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+计算机其他笔记入口
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
记录一下自己新的突破,可能方法比较笨,但还是一行一行敲出来了。
运行如图所示:
总体算法思想:
①首先将中缀表达式转化为后缀表达式
②再计算后缀表达式
模块讲解:
①首先将中缀表达式转化为后缀表达式
计算后缀表达式算法思想:从数组中扫描,
当遇到一个数值时把它压入栈,遇到符号时,
弹出两个值,计算后,压入栈中
优先级口诀:
栈内的 “ *,/ ”符号 大于栈外的,站内的“+ - ” 符号大于栈外的
栈外的 “(” 大于栈内的
操作符 优先级表 | # | ( | *,/ | +,- | ) |
---|---|---|---|---|---|
isp(in Stack priority) | 0 | 1 | 5 | 3 | 6 |
icp(in coming priority) | 0 | 6 | 4 | 2 | 1 |
char* P_to_S(char *arr)//arr作为输入的表达式,比如(a+b)*2-2,注意‘('和')'均为英文输入
{
stack<char> s;
s.push('#');//优先级最低的
char* p =new char(15);//为了在主函数中得到p指向一连串字符串的首地址,在不是函数main中,需要分配持久的内存
int i=0,j=0;
while(arr[i] != '\0')
{
if(arr[i]>='0'&&arr[i]<='9')
p[j++] = arr[i];
else
{
//当栈内有数据时,就需要比较栈内的运算符的优先级
if(isp(s.top())>icp(arr[i]))//isp栈内优先,icp栈外优先数
{
p[j++] = s.top();
s.pop();
}
else if(isp(s.top())==icp(arr[i]))
s.pop();
else
s.push(arr[i]);
}
i++;
}
while(s.top() != '#')
{
if(s.top() == '(')
{
s.pop();
continue;
}
p[j++]=s.top();
s.pop();
}
p[j]='\0';
return p;
}
②再计算后缀表达式
计算后缀表达式算法思想:从数组中扫描,
当遇到一个数值时把它压入栈,遇到符号时,
弹出两个值,计算后,压入栈中
int cal(char* arr)//计算后缀表达式
{
char* p = arr;
int i =0;
int num1=0,num2=0;
while(p[i] != '\0')
{
if(p[i]<='9'&&p[i]>='0')
{
st.push(p[i]-'0');
}
else
{
num2 = st.top();
st.pop();
num1 = st.top();
st.pop();
switch(p[i])
{
case '+':st.push(num1+num2);break;
case '-':st.push(num1-num2);break;
case '*':st.push(num1*num2);break;
case '/':st.push(num1/num2);break;
}
}
i++;
}
return st.top();
}
完整代码:
#include <iostream>
#include <stack>
using namespace std;
stack<int> st;
int cal(char* arr);//计算后缀表达式
int isp(char ch);//返回栈内运算符的优先级
int icp(char ch);//返回栈外运算符的优先级
char* P_to_S(char *arr);
int main()
{
char *arr = new char(10);;
cout<<"请输入一串表达式:如(a+b)/2+3"<<endl;
cin>>arr;
cout<<cal(P_to_S(arr));
return 0;
}
char* P_to_S(char *arr)//将前缀表表达式转化为后缀表达式
{
stack<char> s;
s.push('#');
char* p =new char(15);//为了返回p的地址需要持久化分配内存
int i=0;
int j=0;
while(arr[i] != '\0')
{
if(arr[i]>='0'&&arr[i]<='9')
{
p[j] = arr[i];
j++;
}
else
{
//当栈内有数据时,就需要比较栈内的运算符的优先级
if(isp(s.top())>icp(arr[i]))//isp栈内优先,icp栈外优先数
{
p[j++] = s.top();
s.pop();
}
else if(isp(s.top())==icp(arr[i]))
{
s.pop();
}
else
{
s.push(arr[i]);
}
}
i++;
}
while(s.top() != '#')
{
if(s.top() == '(')
{
s.pop();
continue;
}
p[j++]=s.top();
s.pop();
}
p[j]='\0';
return p;
}
int isp(char ch)//isp==in stack ,根据栈中的符号,返回优先级
{
switch(ch)
{
case '#':return 0;
case '(':return 1;
case '+':return 3;
case '-':return 3;
case '*':return 5;
case '/':return 5;
case ')':return 6;
}
}
int icp(char ch)//in coming==scp ,根据栈中的符号,返回优先级
{
switch(ch)
{
case '#':return 0;
case '(':return 6;
case '+':return 2;
case '-':return 2;
case '*':return 4;
case '/':return 4;
case ')':return 1;
}
}
int cal(char* arr)//计算后缀表达式
{
char* p = arr;
int i =0;
int num1=0,num2=0;
while(p[i] != '\0')
{
if(p[i]<='9'&&p[i]>='0')
{
st.push(p[i]-'0');
}
else
{
num2 = st.top();
st.pop();
num1 = st.top();
st.pop();
switch(p[i])
{
case '+':st.push(num1+num2);break;
case '-':st.push(num1-num2);break;
case '*':st.push(num1*num2);break;
case '/':st.push(num1/num2);break;
}
}
i++;
}
return st.top();
}