/* 中缀转前缀参考算法: 1)求输入串的逆序。(中缀转前缀是从右向左访问表达式) 2)检查输入的下一元素。 3)假如是操作数,把它添加到输出串中。 4)假如是闭括号,将它压栈。 5)假如是运算符, i)假如栈空,此运算符入栈。 ii)假如栈顶是闭括号,此运算符入栈。 iii)假如它的优先级高于或等于栈顶运算符,此运算符入栈。 iv)否则,栈顶运算符出栈并添加到输出串中,重复步骤5。 6)假如是开括号,栈中运算符逐个出栈并输出,直到遇到闭括号。闭括号出栈并丢弃。 7)假如输入还未完毕,跳转到步骤2。 8)假如输入完毕,栈中剩余的所有操作符出栈并加到输出串中。 9)求输出串的逆序。 */
/* 中缀转后缀参考算法: 1)求输入串的正序。(中缀转后缀是从左向右访问表达式) 2)检查输入的下一元素。 3)假如是操作数,把它添加到输出串中。 4)假如是开括号,将它压栈。 5)假如是运算符, i)假如栈空,此运算符入栈。 ii)假如栈顶是开括号,此运算符入栈。 iii)假如它的优先级高于或等于栈顶运算符,此运算符入栈。 iv)否则,栈顶运算符出栈并添加到输出串中,重复步骤5。 6)假如是闭括号,栈中运算符逐个出栈并输出,直到遇到开括号。开括号出栈并丢弃。 7)假如输入还未完毕,跳转到步骤2。 8)假如输入完毕,栈中剩余的所有操作符出栈并加到输出串中。 9)求输出串的正序。 */
/************************ author's email:[email protected] date:2018.1.5 利用顺序栈将中缀式转换成前、后缀式并求值 ************************/ #include <iostream> #include<string> using namespace std; #define maxSize 50 //siffix后缀式 prefix前缀式 infix中缀式 int priority(char op);//判断运算符级别函数;其中* /的级别为2,+ -的级别为1; bool isOperatorDigit(char op);//判断输入串中的字符是不是操作符,如果是返回true int op(int a, char Op, int b);//本函数是运算函数,用来完成算式“a Op b”的运算 string infixConvertPrefix(string s);//将一个中缀串转换为前缀串 int calculatePrefix(string s);//计算前缀式的值 string infixConvertSiffix(string s);//将一个中缀串转换为后缀串 int calculateSiffix(string s);//后缀式计算函数 void main() { //测试表达式为(((((4+2)/3)*5)-4)/2)*7,其前缀式为* / - * / + 4 2 3 5 4 2 7 ,其后缀式为4 2 + 3 / 5 * 4 - 2 / 7 * ,其值为21。 string input, output; cout << "请输入前缀表达式(表达式中的数字只能是个位数):"; cin >> input; output = infixConvertPrefix(input); cout << "前缀串为:"; for (int i = output.length() - 1; i >= 0; i--)//9)求输出串的逆序。 cout << output[i]<<' '; cout << endl; cout << "前缀式的计算结果为:"; cout << calculatePrefix(output) << endl; //string input, output; //cout << "请输入前缀表达式(表达式中的数字只能是个位数):"; //cin >> input; //output = infixConvertSiffix(input); //cout << "后缀串为:"; //for (int i = 0; i <= output.length() - 1; i++)//9)求输出串的逆序。 // cout << output[i]<<' '; //cout << endl; //cout << "后缀式的计算结果为:"; //cout << calculateSiffix(output) << endl; system("pause"); } int priority(char op)//判断运算符级别函数;其中* /的级别为2,+ -的级别为1; { int level; switch (op) { case'+': case'-':level = 1; break; case'*': case'/':level = 2; break; default:level = 0; break; } return level; } bool isOperatorDigit(char op)//判断输入串中的字符是不是操作符,如果是返回true { if (op == '+' || op == '-' || op == '*' || op == '/') return true; else return false; } int op(int a, char Op, int b) {//本函数是运算函数,用来完成算式“a Op b”的运算 if (Op == '+')return a + b; if (Op == '-')return a - b; if (Op == '*')return a*b; if (Op == '/') { if (b == 0)//分母为0的情况 { cout << "Error" << endl; return 0; } else return a / b; } } string infixConvertPrefix(string s)//将一个中缀串转换为前缀串, { char stack[maxSize];//定义顺序栈 int top = -1;//栈顶指针,为-1表示栈为空; string output = "";//输出串 for (int i = s.length() - 1; i >= 0;)//1)求输入串的逆序。 { if (s[i] >= 48 && s[i] <= 57) output = output + s[i];//3)假如是操作数,把它添加到输出串中。 if (s[i] == ')')//4)假如是闭括号,将它压栈。 { top++; stack[top] = s[i]; } while (isOperatorDigit(s[i]))//如果是运算符,执行算法(5)对应操作; { if (top == -1 || stack[top] == ')' || priority(s[i]) >= priority(stack[top])) { top++; stack[top] = s[i]; break; } else { output = output + stack[top]; top--; } } if (s[i] == '(')//6)假如是开括号,栈中运算符逐个出栈并输出,直到遇到闭括号。闭括号出栈并丢弃。 { while (stack[top] != ')') { output = output + stack[top]; top--; } top--;//闭括号出栈并丢弃 } i--;//7)假如输入还未完毕,跳转到步骤2。 } while (top != -1)//8)假如输入完毕,栈中剩余的所有操作符出栈并加到输出串中。 { output = output + stack[top]; top--; } return output; } int calculatePrefix(string s) {//计算前缀式的值 int i, a, b, c;//a、b为操作数,c用来保存结果 /*定义顺序栈,注意元素必须为int型,不能死char型。虽然要求输入的中缀表达式 里面的数字都是个位数,但是运算过程中可能产生多位的数字,所以要用int型*/ int stack[maxSize]; int top = -1;//栈顶指针,为-1表示栈为空; char Op; for (i = 0; i <= s.length() - 1; ++i)//注意此时前缀式的逆序 { if (s[i] >= 48 && s[i] <= 57)//假如是操作数,把它添加到输出串中。 stack[++top] = s[i] - '0';//将字符型转化为整型并入栈 else //如果遇到运算符,则开始运算 { Op = s[i]; //取运算符 a = stack[top--];//取第一个操作数 b = stack[top--];//取第二个操作数 c = op(a, Op, b);//运算 stack[++top] = c;//运算结果入栈 } } return stack[top];//返回最终运算结果 } string infixConvertSiffix(string s) { char stack[maxSize];//定义顺序栈 int top = -1;//栈顶指针,为-1表示栈为空; string output = "";//输出串 for (int i = 0; i <= s.length() - 1;)//1)求输入串的正序。 { if (s[i] >= 48 && s[i] <= 57) output = output + s[i];//3)假如是操作数,把它添加到输出串中。 if (s[i] == '(')//4)假如是开括号,将它压栈。 { top++; stack[top] = s[i]; } while (isOperatorDigit(s[i]))//如果是运算符,执行算法(5)对应操作; { if (top == -1 || stack[top] == '(' || priority(s[i]) >= priority(stack[top])) { top++; stack[top] = s[i]; break; } else { output = output + stack[top]; top--; } } if (s[i] == ')')//6)假如是闭括号,栈中运算符逐个出栈并输出,直到遇到开括号。开括号出栈并丢弃。 { while (stack[top] != '(') { output = output + stack[top]; top--; } top--;//开括号出栈并丢弃 } i++;//7)假如输入还未完毕,跳转到步骤2。 } while (top != -1)//8)假如输入完毕,栈中剩余的所有操作符出栈并加到输出串中。 { output = output + stack[top]; top--; } return output; } int calculateSiffix(string s) {//后缀式计算函数 int i, a, b, c;//a、b为操作数,c用来保存结果 /*定义顺序栈,注意元素必须为int型,不能死char型。虽然要求输入的中缀 表达式里面的数字都是个位数,但是运算过程中可能产生多位的数字,所以 要用int型*/ int stack[maxSize]; int top = -1;//栈顶指针,为-1表示栈为空; char Op; for (i = 0; i <= s.length() - 1; ++i) { if (s[i] >= 48 && s[i] <= 57)//假如是操作数,把它添加到输出串中。 stack[++top] = s[i] - '0';//将字符型转化为整型并入栈 else //如果遇到运算符,则开始运算 { Op = s[i]; //取运算符 //注意这是这里是和计算前缀式的值的区别 b = stack[top--];//取第二个操作数 a = stack[top--];//取第一个操作数 c = op(a, Op, b);//运算 stack[++top] = c;//运算结果入栈 } } return stack[top];//返回最终运算结果 }以上如有错误,请指出,大家共同学习进步