中缀到后缀程序
infix to postfix program
我已经编写了以下中缀到后缀程序,但它不起作用。我的程序接受输入,但没有显示任何结果。有人能帮我找出程序中的问题吗。如果你能告诉我的将中缀转换为后缀的算法是否正确,这将是一个很大的帮助。
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
语句需要default
s。数字字符("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;
}
- Mongodb c++驱动程序:如何查询元素的数组
- C++,系统无法执行指定的程序
- 在C++程序中输入的文本文件将不起作用,除非文本被复制和粘贴
- 在VS代码中交叉编译Windows与Linux上的MinGW的SDL程序
- 增量运算符与后缀混淆
- C++ Windows 驱动程序MSB3030无法复制该文件,因为它找不到
- 重载操作程序时出错>>用于类中的字符串 memebr
- 获取日期异步信号安全吗?如果在信号处理程序中使用,它会导致死锁吗
- 试图在visual studio上用C++创建一个桌面应用程序
- 模板元程序查找相似的连续类型名称
- FFmpeg:制作一个应用程序比直接使用ffmepg更好吗
- 如何通过cpp程序运行shell脚本
- 有没有什么方法可以使用一个函数中定义的常量变量,也可以由c++中同一程序中的其他函数使用
- IPC使用多个管道和分支进程来运行Python程序
- 如何将c++程序的一些输出传递给shell,以便在shell中使用
- 使用C++程序合并排序没有得到正确的输出
- 为什么 C++ 程序员更喜欢前缀 ++,而 Java 程序员更喜欢后缀 ++?
- 中缀到后缀程序
- 中缀到后缀转换器 + 评估程序正确打印到控制台,但不正确地打印到文本文件
- 将后缀转换为求值的程序