class — Преобразование из инфикса в постфикс

Я пытаюсь преобразовать из инфикса в постфикс, а затем оценивает выражение постфикса, чтобы получить окончательный ответ. У меня серьезная проблема, потому что по какой-то причине преобразование не работает вообще. Например, когда я ввожу первое инфиксное выражение: 24 + 33 * (7 — 5) + 8/3, оно выдает 24 33 7 5 45404243 8 34743, что, очевидно, очень неправильно. Я не совсем уверен, где проблема, хотя. Ниже я включил весь необходимый код. Я также должен был создать свой собственный класс стека, поэтому я включу его тоже, если это поможет. Любые советы будут с благодарностью!

#include "stacks.h"#include <iostream>
#include <string>using namespace std;

bool IsOperand(char C)
{
if(C >= '0' && C <= '9') return true;
return false;
}

bool IsOperator(char C)
{
if(C == '+' || C == '-' || C == '*' || C == '/')
return true;

return false;
}
int GetOperatorWeight(char op)
{
int weight = -1;
switch(op)
{
case '+':
case '-':
weight = 1;
case '*':
case '/':
weight = 2;
}
return weight;
}

int HasHigherPrecedence(char op1, char op2)
{
int op1Weight = GetOperatorWeight(op1);
int op2Weight = GetOperatorWeight(op2);

return op1Weight > op2Weight ?  true: false;
}

int PerformOperation(char operation, int operand1, int operand2)
{
if(operation == '+') return operand1 +operand2;
else if(operation == '-') return operand1 - operand2;
else if(operation == '*') return operand1 * operand2;
else if(operation == '/') return operand1 / operand2;

else cout<<"Unexpected Error \n";
return -1;
}

bool IsNumericDigit(char C)
{
if(C >= '0' && C <= '9') return true;
return false;
}

int evalPost(string item)
{
stacks S;

for(int i = 0;i< item.length();i++) {if(item[i] == ' ' || item[i] == ',') continue;

else if(IsOperator(item[i])) {

int operand2 = stoi(S.stackTop()); S.pop();
int operand1 = stoi(S.stackTop()); S.pop();

int result = PerformOperation(item[i], operand1, operand2);

S.push(to_string(result));
}
else if(IsNumericDigit(item[i]))
{
int operand = 0;
while(i<item.length() && IsNumericDigit(item[i]))
{
operand = (operand*10) + (item[i] - '0');
i++;
}

i--;

S.push(to_string(operand));
}
}
return stoi(S.stackTop());
}string infToPost(string item)
{
stacks S;
string postfix = "";
for(int i = 0;i< item.length();i++) {
cout<<postfix<<endl;
if(item[i] == ' ')
postfix +=item[i];

else if(IsOperator(item[i]))
{

while(!S.empty() && S.stackTop() != "(" && HasHigherPrecedence(*(S.stackTop().c_str()),item[i]))
{
postfix+= S.stackTop();
S.pop();
}
S.push(to_string(item[i]));
//S.pop();
}

else if(IsOperand(item[i]))
{
postfix +=item[i];
}

else if (item[i] == '(')
{
S.push(to_string(item[i]));
}

else if(item[i] == ')')
{
while(!S.empty() && S.stackTop() !=  "(") {
postfix += S.stackTop();
S.pop();
}
S.pop();
}
}while(!S.empty()) {
postfix += S.stackTop();
S.pop();
}

return postfix;
}

int main()
{
string selection="";
string infix;
string postfix;
string eval;
cout<<"***********************************************************"<<endl;
cout<<"1. Read an expression in infix notation."<<endl;
cout<<"2. Convert infix to postfix."<<endl;
cout<<"3. Evaluate the expression using postfix notation."<<endl;
cout<<"4. Exit"<<endl;
cout<<"***********************************************************"<<endl;
cout<<"Select: ";
getline(cin, selection);
//    cin>>selection;
//    cin.ignore();
while (selection>"4" || selection<"1")
{
cout<< "Please enter a different choice (1-4): ";
getline(cin, selection);
}
while(selection!="4")
{

if (selection=="1")
{
cout<<"Enter an infix expression: ";
getline(cin,infix);
cout<<"\n";
}

if(selection=="2")
{
cout<<"Infix expression: "<<infix<<endl;
postfix = infToPost(infix);
cout<<"Postfix expression: "<<postfix<<endl;
cout<<"\n";
}

if(selection=="3")
{
cout<<"Infix expression: "<<infix<<endl;
eval = evalPost(postfix);
cout<<"Evaluation of this expression: "<<endl;
cout<<"\n";
}

selection = "";
cout<<"***********************************************************"<<endl;
cout<<"1. Read an expression in infix notation."<<endl;
cout<<"2. Convert infix to postfix."<<endl;
cout<<"3. Evaluate the expression using postfix notation."<<endl;
cout<<"4. Exit"<<endl;
cout<<"***********************************************************"<<endl;
cout<<"Select: ";
getline(cin,selection);
//cin.ignore();
while (selection>"4" || selection<"1")
{
cout<< "Please enter a different choice (1-4): ";
getline(cin, selection);
}
}
cout<<"Thank you for using my program."<<endl;
return 0;

}

СТЕКЛА КЛАСС

#ifndef __Programming_Assingment_3__stacks__
#define __Programming_Assingment_3__stacks__
#include <string>
#include <vector>
using namespace std;

//define the stacks class
class stacks
{
public:
//constructor
stacks();
//push function
void push(string item);
//pop function
void pop();
//function to get top of stack
string stackTop();
//check if stack is empty
bool empty();
private:
//create vector and integer
int top;
vector<string> sstack;
};

#endif /* defined(__Programming_Assingment_3__stacks__) */

STACK CLASS CPP FILE

#include "stacks.h"#include <iostream>
#include <string>

using namespace std;

//Contstructor
stacks::stacks()
{
top = -1;
}

//push the item onto the stack
void stacks::push(string item)
{
sstack.push_back(item);
top++;
}

//check if the stack is empty
bool stacks::empty()
{
if (top==-1)
return true;
else
return false;
}

//delete the last item on the stack
void stacks::pop()
{
try{
if (sstack.size()==0) throw 0;
} catch(int err){
cout<<"stack is empty."<<endl;
cout<<"Cannot pop an item."<<endl;
return;
}
sstack.pop_back();
top--;
}

//get the top of the stack
string stacks::stackTop()
{
try{
if (sstack.size()==0) throw 0;
} catch (int err) {
cout<< "stack is empty."<<endl;
return 0;
}
return (sstack[top]);
}

0

Решение

Когда вы помещаете оператор в свой стек, используя эту строку:

S.push(to_string(item[i]));

to_string берет символ и рассматривает его как целое число. Это приводит к таким строкам, как «43» для «+» и «45» для «-».

Вместо этого вы хотите создать строку, содержащую только этот символ. Одним из способов сделать это является использование строкового конструктора, который принимает значение счетчика и значение символа. Используйте счет 1.

S.push(std::string(1, item[i]));

Редактировать: вот infoToPost функция с изменениями. Не меняйте ни одного другого to_string вызовы в других методах, поскольку они все еще необходимы (потому что вы хотите преобразовать целочисленные значения в строки).

string infToPost(string item)
{
stacks S;
string postfix = "";
for (int i = 0; i< item.length(); i++) {
cout << postfix << endl;
if (item[i] == ' ')
postfix += item[i];

else if (IsOperator(item[i]))
{

while (!S.empty() && S.stackTop() != "(" && HasHigherPrecedence(*(S.stackTop().c_str()), item[i]))
{
postfix += S.stackTop();
S.pop();
}
S.push(string(1, item[i]));
//S.pop();
}

else if (IsOperand(item[i]))
{
postfix += item[i];
}

else if (item[i] == '(')
{
S.push(string(1, item[i]));
}

else if (item[i] == ')')
{
while (!S.empty() && S.stackTop() != "(") {
postfix += S.stackTop();
S.pop();
}
S.pop();
}
}while (!S.empty()) {
postfix += S.stackTop();
S.pop();
}

return postfix;
}
1

Другие решения


По вопросам рекламы [email protected]