我的讲师给了我一个任务,让我创建一个程序,使用堆栈将表达式和中缀转换为后缀。我制作了堆栈类和一些函数来读取中缀表达式。
但是这个函数,叫做transtToPostfix(char*const inFix,char*const postFix)
,它负责使用堆栈将数组inFix中的inFix表达式转换为数组postFix中的postfix表达式,并没有做它应该做的事情...你们能帮帮我告诉我哪里做错了吗?
下面是从中缀转换为后缀的函数的代码,convertToPostfix(char*const-inFix,char*const-postFix)
是我需要帮助修复的代码:
void ArithmeticExpression::inputAndConvertToPostfix()
{
char inputChar; //declaring inputChar
int i = 0; //inizalize i to 0
cout << "Enter the Arithmetic Expression(No Spaces): ";
while( ( inputChar = static_cast<char>( cin.get() ) ) != '\n' )
{
if (i >= MAXSIZE) break; //exits program if i is greater than or equal to 100
if(isdigit(inputChar) || isOperator(inputChar))
{
inFix[i] = inputChar; //copies each char to inFix array
cout << inFix[i] << endl;
}
else
cout << "You entered an invalid Arithmetic Expression\n\n" ;
}
// increment i;
i++;
convertToPostfix(inFix, postFix);
}
bool ArithmeticExpression::isOperator(char currentChar)
{
if(currentChar == '+')
return true;
else if(currentChar == '-')
return true;
else if(currentChar == '*')
return true;
else if(currentChar == '/')
return true;
else if(currentChar == '^')
return true;
else if(currentChar == '%')
return true;
else
return false;
}
bool ArithmeticExpression::precedence(char operator1, char operator2)
{
if ( operator1 == '^' )
return true;
else if ( operator2 == '^' )
return false;
else if ( operator1 == '*' || operator1 == '/' )
return true;
else if ( operator1 == '+' || operator1 == '-' )
if ( operator2 == '*' || operator2 == '/' )
return false;
else
return true;
return false;
}
void ArithmeticExpression::convertToPostfix(char * const inFix, char * const postFix)
{
Stack2<char> stack;
const char lp = '(';
stack.push(lp); //Push a left parenthesis ‘(‘ onto the stack.
strcat(inFix,")");//Appends a right parenthesis ‘)’ to the end of infix.
// int i = 0;
int j = 0;
if(!stack.isEmpty())
{
for(int i = 0;i < 100;){
if(isdigit(inFix[i]))
{
postFix[j] = inFix[i];
cout << "This is Post Fix for the first If: " << postFix[j] << endl;
i++;
j++;
}
if(inFix[i] == '(')
{
stack.push(inFix[i]);
cout << "The InFix was a (" << endl;
i++;
//j++;
}
if(isOperator(inFix[i]))
{
char operator1 = inFix[i];
cout << "CUrrent inFix is a operator" << endl;
if(isOperator(stack.getTopPtr()->getData()))
{
cout << "The stack top ptr is a operator1" << endl;
char operator2 = stack.getTopPtr()->getData();
if(precedence(operator1,operator2))
{
//if(isOperator(stack.getTopPtr()->getData())){
cout << "The stack top ptr is a operato2" << endl;
postFix[j] = stack.pop();
cout << "this is post fix " << postFix[j] << endl;
i++;
j++;
// }
}
}
else
stack.push(inFix[i]);
// cout << "Top Ptr is a: "<< stack.getTopPtr()->getData() << endl;
}
for(int r = 0;r != '\0';r++)
cout << postFix[r] << " ";
if(inFix[i] == ')')
{
while(stack.stackTop()!= '(')
{
postFix[j] = stack.pop();
i++;
j++;
}
stack.pop();
}
}
}
}
注意:convertToPostfix函数是使用以下算法生成的:
>
>
如果内缀中的当前字符是运算符,
这是我用C和多个数字的评估。
#include <stdio.h>
#include <math.h>
#define MAX 50
void push(char[],char);
void in_push(double[], double);
int pop();
int prec(char);
double eval(char[],int,double[]);
int top = 0;
void main() {
double eval_stack[MAX];
int op_count=0;
char stack[MAX], exps[MAX], symbols[MAX];
int i=0,j=0,len,check;
while((symbols[i]=getchar())!='\n') {
if(symbols[i]!=' ' || symbols[i]!='\t') {
if(symbols[i]=='+' || symbols[i]=='-' || symbols[i]=='/' || symbols[i]=='*' || symbols[i]=='^')
op_count++;
i++;
}
}
symbols[i]='#';
symbols[++i]='\0';
len = strlen(symbols);
stack[top] = '#';
for(i=0; i<=len; i++) {
if(symbols[i]>='a' && symbols[i]<='z') {
exps[j]=symbols[i];
j++;
}
switch(symbols[i]) {
case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
//if(symbols[i]>='a' && symbols[i]<='z') {
exps[j]=symbols[i];
j++;
break;
case '+': case '-': case '*': case '/': case '^':
exps[j++] = ' ';
while(prec(symbols[i]) <= prec(stack[top])) {
exps[j] = stack[top];
pop();
//printf("\n\t\t%d\t\t%d\n", top,j);
j++;
}
if(prec(symbols[i]) > prec(stack[top])) {
push(stack,symbols[i]);
}
break;
case '(':
push(stack,symbols[i]);
break;
case ')':
while(stack[top]!='(') {
exps[j] = stack[top];
pop();
j++;
}
pop();
break;
case '#':
exps[j++] = ' ';
while(stack[top]!='#') {
exps[j] = stack[top];
pop();
j++;
}
pop();
break;
}
}
exps[j]='\0';
printf("Postfix: %s", exps);
for(i=0; i<j; i++)
if(exps[i]=='a')
check = 1;
if(check!=1)
printf("\nSolution: %.1f", eval(exps,j,eval_stack));
}
double eval(char exps[],int exps_len,double eval_stack[]) {
int i; int len=exps_len,temp;
double in_temp[MAX],t;
int count,power,j,in_count;
count=power=j=t=in_count=0;
double result;
for(i=0; i<len; i++) {
switch(exps[i]) {
case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
in_temp[i] = exps[i]-'0';
j=i+1;
while(exps[j]>='0' && exps[j]<='9') {
in_temp[j] = exps[j]-'0';
j++; // 2
}
count = i; // 3
while(in_temp[count]<='0' && in_temp[count]<='9') {
power = (j-count)-1;
t = t + in_temp[count]*(pow(10,power));
power--;
count++;
}
in_push(eval_stack,t);
i=j-1;
t=0;
break;
case '+':
temp = pop();
pop();
result = eval_stack[temp] + eval_stack[temp+1];
in_push(eval_stack,result);
break;
case '-':
temp = pop();
pop();
result = eval_stack[temp] - eval_stack[temp+1];
in_push(eval_stack,result);
break;
case '*':
temp = pop();
pop();
result = eval_stack[temp] * eval_stack[temp+1];
in_push(eval_stack,result);
break;
case '/':
temp = pop();
pop();
result = eval_stack[temp] / eval_stack[temp+1];
in_push(eval_stack,result);
break;
case '^':
temp = pop();
pop();
result = pow(eval_stack[temp],eval_stack[temp+1]);
in_push(eval_stack,result);
break;
}
}
return eval_stack[top];
}
int prec(char a) {
if(a=='^')
return 3;
else if(a=='*' || a=='/' || a=='%')
return 2;
else if(a=='+' || a=='-')
return 1;
else if(a=='(')
return 0;
else
return -1;
}
void push(char stack[], char ele) {
if(top>=MAX) {
printf("\nStack Overflow");
exit(1);
}
stack[++top] = ele;
}
void in_push(double stack[], double ele) {
if(top>=MAX) {
printf("\nStack Overflow");
exit(1);
}
stack[++top] = ele;
}
int pop() {
if(top<0) {
printf("\nStack Underflow");
exit(1);
}
top = top - 1;
return top;
}
因此,您的代码存在许多问题。我将发布(应该是)一个纠正的解决方案,其中有大量的评论来解释发生了什么以及你在哪里犯了错误。前面有几件事:
>
我正在使用标准库中的堆栈
它是一个自由函数,不是类的一部分,但应该很容易修改——这样测试对我来说很简单。
我不相信你的操作员优先级表是正确的,但是,我会让你仔细检查一下。
#include <stack>
#include <cctype>
#include <iostream>
std::string convertToPostfix(std::string& infix)
{
std::string postfix; //Our return string
std::stack<char> stack;
stack.push('('); //Push a left parenthesis ‘(‘ onto the stack.
infix.push_back(')');
//We know we need to process every element in the string,
//so let's do that instead of having to worry about
//hardcoded numbers and i, j indecies
for(std::size_t i = 0; i < infix.size(); ++i) {
//If it's a digit, add it to the output
//Also, if it's a space, add it to the output
//this makes it look a bit nicer
if(isdigit(infix[i]) || isspace(infix[i])) {
postfix.push_back(infix[i]);
}
//Already iterating over i, so
//don't need to worry about i++
//Also, these options are all mutually exclusive,
//so they should be else if instead of if.
//(Mutually exclusive in that if something is a digit,
//it can't be a parens or an operator or anything else).
else if(infix[i] == '(') {
stack.push(infix[i]);
}
//This is farily similar to your code, but cleaned up.
//With strings we can simply push_back instead of having
//to worry about incrementing some counter.
else if(isOperator(infix[i]))
{
char operator1 = infix[i];
if(isOperator(stack.top())) {
while(!stack.empty() && precedence(operator1,stack.top())) {
postfix.push_back(stack.top());
stack.pop();
}
}
//This shouldn't be in an else - we always want to push the
//operator onto the stack
stack.push(operator1);
}
//We've hit a right parens - Why you had a for loop
//here originally I don't know
else if(infix[i] == ')') {
//While top of stack is not a right parens
while(stack.top() != '(') {
//Insert into postfix and pop the stack
postfix.push_back(stack.top());
stack.pop();
}
// Discard the left parens - you'd forgotten to do this
stack.pop();
}
}
//Remove any remaining operators from the stack
while(!stack.empty()) {
postfix.push_back(stack.top());
stack.pop();
}
}
这基本上是对Yuushi回答的评论。
优先(rightOp,leftOp)
)。然后,您应该记录结果的含义-如果a rOp b lOp c==(a rOp b)lOp c
(是的,运算符顺序与您所称的不匹配,例如-“”和“-”在两个顺序中都不相同,那么现在返回true)
a-b*c
后,您的输出是a-b-c
,堆栈是[-*]
。现在您阅读了一个
,需要同时弹出两个操作符,结果是abc*-
。即,输入a-b*cd
应导致a-b*cd
更新:附加完整的解决方案(基于Yuushi的回答):
bool isOperator(char currentChar)
{
switch (currentChar) {
case '+':
case '-':
case '*':
case '/':
case '^':
case '%':
return true;
default:
return false;
}
}
// returns whether a `lOp` b `rOp` c == (a `lOp` b) `rOp` c
bool precedence(char leftOperator, char rightOperator)
{
if ( leftOperator == '^' ) {
return true;
} else if ( rightOperator == '^' ) {
return false;
} else if ( leftOperator == '*' || leftOperator == '/' || leftOperator == '%' ) {
return true;
} else if ( rightOperator == '*' || rightOperator == '/' || rightOperator == '%' ) {
return false;
}
return true;
}
#include <stdexcept>
#include <cctype>
#include <sstream>
#include <stack>
std::string convertToPostfix(const std::string& infix)
{
std::stringstream postfix; // Our return string
std::stack<char> stack;
stack.push('('); // Push a left parenthesis ‘(‘ onto the stack.
for(std::size_t i = 0, l = infix.size(); i < l; ++i) {
const char current = infix[i];
if (isspace(current)) {
// ignore
}
// If it's a digit or '.' or a letter ("variables"), add it to the output
else if(isalnum(current) || '.' == current) {
postfix << current;
}
else if('(' == current) {
stack.push(current);
}
else if(isOperator(current)) {
char rightOperator = current;
while(!stack.empty() && isOperator(stack.top()) && precedence(stack.top(), rightOperator)) {
postfix << ' ' << stack.top();
stack.pop();
}
postfix << ' ';
stack.push(rightOperator);
}
// We've hit a right parens
else if(')' == current) {
// While top of stack is not a left parens
while(!stack.empty() && '(' != stack.top()) {
postfix << ' ' << stack.top();
stack.pop();
}
if (stack.empty()) {
throw std::runtime_error("missing left paren");
}
// Discard the left paren
stack.pop();
postfix << ' ';
} else {
throw std::runtime_error("invalid input character");
}
}
// Started with a left paren, now close it:
// While top of stack is not a left paren
while(!stack.empty() && '(' != stack.top()) {
postfix << ' ' << stack.top();
stack.pop();
}
if (stack.empty()) {
throw std::runtime_error("missing left paren");
}
// Discard the left paren
stack.pop();
// all open parens should be closed now -> empty stack
if (!stack.empty()) {
throw std::runtime_error("missing right paren");
}
return postfix.str();
}
#include <iostream>
#include <string>
int main()
{
for (;;) {
if (!std::cout.good()) break;
std::cout << "Enter the Arithmetic Expression: ";
std::string infix;
std::getline(std::cin, infix);
if (infix.empty()) break;
std::cout << "Postfix: '" << convertToPostfix(infix) << "'\n";
}
return 0;
}
本文向大家介绍将中缀转换为后缀表达式,包括了将中缀转换为后缀表达式的使用技巧和注意事项,需要的朋友参考一下 前缀表达式是人类可读和可解的。我们可以轻松地区分算子的顺序,也可以在计算数学表达式时先使用括号将其求解。计算机无法轻松地区分运算符和括号,这就是为什么需要后缀转换的原因。 要将中缀表达式转换为后缀表达式,我们将使用堆栈数据结构。通过从左到右扫描infix表达式,当我们得到任何操作数时,只需将
我正在为我的一堂计算机科学课开发一个计算后缀表达式结果的程序。该程序使用堆栈ADT来实现这一点。 我已经编写了程序,但相信可能会有错误,因为一些表达式的结果不正确。我不确定我的错误在哪里。 此外,当输入文件为空时,程序将生成一个值32767。那是从哪里来的? 表达式:34+3*值=21。 主程序:
本文向大家介绍将中缀转换为前缀表达式,包括了将中缀转换为前缀表达式的使用技巧和注意事项,需要的朋友参考一下 要通过计算机求解表达式,我们可以将其转换为后缀形式或前缀形式。在这里,我们将看到中缀表达式如何转换为前缀形式。 首先,中缀表达式反转。注意,对于反转,圆括号也将反转。 例如:表达式:A + B *(C-D) 反转后的表达式为:)D – C(* B + A 因此我们需要将左括号转换为右括号,反
本文向大家介绍中缀表达式转后缀表达式相关面试题,主要包含被问及中缀表达式转后缀表达式时的应答技巧和注意事项,需要的朋友参考一下 参考回答: 对于中缀表达式,遇到操作数直接将其输出,如果遇到操作符和左括号全部压入栈中,若遇到右括号则将栈中元素全部弹出,直到遇到左括号为止。压栈过程中,若遇到其它操作符,从栈中弹出元素直到遇到更低优先级的操作符为止。
我的讲师给了我一个任务,创建一个程序,使用堆栈将中缀表达式转换为后缀。我制作了堆栈类和一些函数来读取中缀表达式。 但是这个名为inToPos(charstring[])的函数正在创建断点,该函数负责使用堆栈将字符串中缀中的中缀表达式转换为字符串后缀中的后缀表达式。你们能帮帮我,告诉我我做错了什么吗? 这些是我的代码,非常需要您的帮助:) 注:inToPos功能是使用以下算法实现的: 从左到右扫描中
我试图在1次传递中评估一个内插表达式,而不将其转换为后缀,但它没有为某些表达式提供正确的输出。例如:3-5*10/5 10 , (45 5)-5*(100/10) 5 是否有人能在cpp中为这个问题提供适当的解决方案。 链接到上一个问题:如何使用堆栈在一次扫描中计算中缀表达式? 请不要将其标记为重复,因为我已经尝试了上述给定线程中回答的算法,但没有效果。