中缀到后缀程序

infix to postfix program

本文关键字:程序 后缀 中缀      更新时间:2023-10-16

我已经编写了以下中缀到后缀程序,但它不起作用。我的程序接受输入,但没有显示任何结果。有人能帮我找出程序中的问题吗。如果你能告诉我的将中缀转换为后缀的算法是否正确,这将是一个很大的帮助。

using namespace std;
class Stack
{
private:
int top;
char s[mx];
public:
Stack()
{
top=-1;
}
void push(char c)
{
if(!stackFull())
s[++top]=c;
}
void pop()
{
if(!stackEmpty())
top--;
else cout<<"Stack is empty"<<endl;
}
char topShow()
{
if(!stackEmpty())
return s[top];
}
bool stackEmpty()
{
if(top==-1)
return 1;
else return 0;
}
bool stackFull()
{
if(top == (mx-1))
return 1;
else return 0;
}
};
class Expression
{
private:
char entry2;
int precedence;
char infix[mx];
char postfix[mx];
public:
int prec(char symbol)
{
switch(symbol)
{
case '(':return 0; break;
case '-':return 1; break;
case '+':return 2; break;
case '*':return 3; break;
case '/':return 4; break;
}
}
void Read()
{
cout<<"Enter the infix expression: ";cin>>infix;
for(int i=0;infix[i]!='';i++)
{
convertToPostfix(infix[i]);
}
}
void ShowResult()
{
cout<<"Postfix expression"<<endl;
for(int j=0;postfix[j]!='';j++)
{
cout<<postfix[j];
}
}
void convertToPostfix(char c)
{
int p=0;
Stack myStack;
precedence=prec(c);
entry2=myStack.topShow();
if(isdigit(c))
{
postfix[++p]=c;
}
if(precedence>prec(entry2))
{
myStack.push(c);
}
if(precedence<prec(entry2))
{
switch(c)
{
case '(': myStack.push(c); break;
case ')': while(myStack.topShow()!= '(')
{
postfix[++p]=myStack.topShow();
myStack.pop();
};myStack.pop();break;
case '+':
case '-':
case '*':
case '/': while(prec(myStack.topShow())>=precedence)
{
postfix[++p]=myStack.topShow();
myStack.pop();
};break;
}
}
}
};
int main()
{
Expression myExp;
myExp.Read();
myExp.ShowResult();
return 0;
}

以下是我发现的一些问题:

布尔函数返回true或false将返回类型与返回值匹配。数字1和0不是布尔值。

优先级表
加法和减法具有相同的优先级
乘法和除法具有相同的优先级
乘法和除法的优先级高于加法和减法。

堆栈消失
由于堆栈在函数中被声明为局部变量,因此在进入函数时会重新创建,并在退出函数前销毁。

解决方案:将其作为类成员移动到类中,或将其声明为static

每行多个语句的效率并不高
空行和换行不会影响性能,并且会为构建增加微不足道的时间
但是,它们使程序可读性更强,这有助于检查或调试。使用它们。

与运算符前后的空格类似
现在就养成这个习惯,而不是在找到工作后再改正。

调用函数一次并存储值
您调用prec(entry2)两次,这是浪费时间。调用一次并将值保存在变量中。与CCD_ 3类似。

使用std::vector而不是数组
std::vector将根据需要增长并减少缓冲区溢出的机会
使用数组时,必须检查索引是否始终在范围内。此外,阵列容量不变;您必须声明一个新实例并复制数据。

变量mx未声明
编译器应捕获此变量。您使用mx作为阵列的容量,并比较完整。然而,它从未被声明、定义或初始化。更喜欢std::vector,您就不必处理这些问题了。

输入未验证
您输入了一个字母,但未验证。
请尝试以下字符:空格、#、@、a、B等。

开关缺少默认值
将编译器警告设置为最大值。您的switch语句需要defaults。数字字符("0".."9")的优先级是多少
(您可以检查数字字符的优先级。)

检查函数和程序中的所有路径使用调试器(请参阅下文)或纸笔,通过函数检查程序流。包括边界值和不在边界内的值。

事例语句:break或return
return语句之后不需要break。想想看,程序能在return语句之后的那一行继续执行吗?

使用调试器或打印语句
您可以在程序的不同点打印变量。当调试器不可用时,这是一种古老的技术
学习使用调试器。大多数IDE都附带了它们。您可以单步执行每个语句并打印出变量值。非常非常有用。

class infixToPostfix{
public static void postfix(String str){
Stack<Character> stk = new Stack<Character>();
for(Character c : str.toCharArray()){
// If operands appears just print it
if(c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z'){
System.out.print(c);
}else{ 
// Open paranthesis push is 
if(c == '('){
stk.push(c);
//Close paranthesis pop until close paranthesis
}else if( c == ')'){
while(stk.peek() != '(')
System.out.print(stk.pop());
stk.pop();
// check the precedence of operator with the top of stack
}else if(c == '+' || c == '-'){
if(!stk.isEmpty()){
char top = stk.peek();
if(top == '*' || top == '/' || top == '+' || top == '-'){
System.out.print(stk.pop());    
}
}   
stk.push(c);
}else{
if(!stk.isEmpty()){
char top = stk.peek();
if(top == '/' || top == '*'){
System.out.print(stk.pop());
}
}   
stk.push(c);
}
}
}
//Print all the remaining operands
while(!stk.isEmpty()) System.out.print(stk.pop());
System.out.println();
}
public static void main(String args[]){
String str = "A+B-(c+d*Z+t)/e";
postfix(str);
}
}

使用堆栈和映射u可以解决问题
1)创建一个以运算符为键和一些整数设置优先级的映射。具有相同优先级的运算符将具有相同的值,例如:

map<char,int>oprMap;
oprMap['^'] = 3;
oprMap['*'] = 2;
oprMap['/'] = 2;
oprMap['+'] = 1;
oprMap['-'] = 1;

2) 遍历给定的表达式调用这些检查
1)如果当前元素
i)是操作数,则将其添加到结果
ii)不是操作数,执行以下检查
a.而不是(堆栈为空,元素为开括号,并找到优先级更高的运算符。将堆栈顶部添加到结果中并pop()
b.将当前元素推送到堆栈

iii)如果打开的括号被推到堆栈
iv)如果关闭的括号弹出,直到得到关闭的括号并将其添加到结果

3) 而stack不为空pop(),并将top元素添加到结果中。

{       
stack<char>S;
for (int i = 0; i < n; i++)  {
if(isOperand(exps[i])) {
res = res + exps[i];
} else if(isOperator(exps[i])){
while(!(S.empty() && isOpenParanthesis(S.top()) && isHeigherPrecedence(S.top(),exps[i])){
res = res+S.top();
S.pop();
}  
S.push(exps[i]);
} else if(isOpenParanthesis(exps[i])) {
S.push(exps[i]);
} else if(isClosingParanthesis(exps[i])) {
while(!S.empty() && !isOpenParanthesis(S.top())) {
res = res+S.top();
S.pop();
}
S.pop();
}
}
while(!S.empty()) {
res = res + S.top();
S.pop();
}
}
}
#include<bits/stdc++.h>
using namespace std;

//此isHigher功能检查字符a的优先级高于b。

bool isHigher(char a,char b)
{
if(a=='+' || a=='-')
return false;
else if((a=='*' && b=='*') || (a=='*' && b=='/') || (a=='/' && b=='*') ||          
(a=='/' && b == '/')|| (a=='^' && b=='^')||(a=='*' && b=='^') || (a=='/' && 
b=='^'))
return false;
return true;
}
int main(){
string s;
cin>>s;
s = s + ")";
//Vector postfix contains the postfix expression.
vector<char>postfix;
stack<char>mid;
mid.push('(');
for(int i=0;i<s.length();i++)
{
if(s[i] == '(')
mid.push(s[i]);
else if(s[i] == '+' || s[i] == '^' || s[i] == '-' || s[i] == '*'|| 
s[i] == '/')
{
if(mid.top() == '(')
mid.push(s[i]);
else {
if(isHigher(s[i],mid.top()))
mid.push(s[i]);
else
{
while(mid.top()!='(')
{
if(!isHigher(s[i],mid.top()))
{
postfix.push_back(mid.top());
mid.pop();  
}
else
break;
}
mid.push(s[i]);
}
}
}
else if(s[i] == ')')
{
while(mid.top() != '(')
{
postfix.push_back(mid.top());
mid.pop();      
}
mid.pop();
}
else
postfix.push_back(s[i]);
}
for(int i=0;i<postfix.size();i++)
cout<<postfix[i];
return 0;

}