Пример программы Binary Operads - PullRequest
0 голосов
/ 17 ноября 2011

Постановка проблемы : Напишите программу на C ++ для оценки выражений postfix. Ваша программа должна принимать постфиксное выражение в качестве входных данных, обрабатывать его с помощью стека и отображать результат после выполнения необходимых вычислений.

Для этой программы разрешены только следующие бинарные операторы: +, -, *, /, ^ [сложение, вычитание, умножение, деление, возведение в степень]

Если при обработке выражения postfix возникает какая-либо ошибка, ваша программа должна отображать значимое сообщение, например: Ошибка: деление на ноль не допускается Ошибка: два оператора необходимы для оператора __ Ошибка: неверное постфиксное выражение

Помогите мне, моя программа генерирует ошибки Это моя попытка:

#include<iostream>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<string>

#define MAX_SIZE 20

using namespace std;
template<class T>
class Stack
{
private:
    T item[MAX_SIZE];
    int top;
public:
    Stack()
    {
        top = -1;
    }

    void push(T data)
    {
        if(!this->is_full())
            item[++top] = data;
        else
        {
            cout<<"Stack Error"<<endl;
            exit(10);
        }
    }
    T pop()
    {
        if(!this->is_empty())
            return item[top--];
        else
        {
            cout<<"Stack is Empty"<<endl;
            exit(11);
        }
    }

    int size()
    {
        return top+1;
    }

    bool is_empty()
    {
        if(top==-1)
            return true;
        else
            return false;
    }

    bool is_full()
    {
        if(top==MAX_SIZE-1)
            return true;
        else
            return false;
    }

    void display()
    {
        for(int i=0; i<this->size(); i++)
        {
            cout<<item[i]<<" ";
        }
        cout<<endl;
    }
    T return_top()
    {
        return item[top];
    }
};

class Convert
{
private:
    bool num_flag;
    bool tow_digit_flag;
public:
    Convert();
    string return_with_bracket(string infix);
    void to_Postfix(string infix,char postfix[]);
    bool prcd(char op1, char op2);
    int isOperand(char op);
    int isOperator(char op);
    bool return_flag()
    {
        return num_flag;
    }
};

Convert::Convert()
{
    this->num_flag = false;
    this->tow_digit_flag = false;
}
string Convert::return_with_bracket(string infix)
{
    return("(" + infix + ")");
}

bool Convert::prcd(char op1, char op2)
{
    if((op1=='+' || op1=='-' || op1=='*' || op1=='/') && op2=='(' )
        return true;
    if(op1=='+' && op2=='+')
        return true;
    if(op1=='-' && op2=='-')
        return false;
    if(op1=='-' && op2=='+')
        return false;
    if(op1=='+' && op2=='-')
        return false;
    if(op1=='/' && op2=='/')
        return false;
    if(op1=='/' && (op2=='-' || op2=='+'))
        return true;
    if(op1=='*' && (op2=='+' || op2=='-'))
        return true;
    if((op1 == '-' || op1 == '+') && (op2 =='*' || op2 == '/'))
        return false;
    if((op1=='$' || op1 == '+') && (op2 =='*' || op2 == '/' || op2=='-'))
        return true;
    if((op1 == '-' || op1 == '+' || op1 =='*' || op1 == '/')&& op2=='^')
        return false;
    if(op1 == '^' && ( op2 == '+' || op2 =='*' || op2 == '/' || op2=='-'))
        return false;
}

int Convert::isOperand(char op)
{
    return(op>= '0' && op <= '9');
}

int Convert::isOperator(char op)
{
    return(op=='+' || op=='-' || op == '/' || op=='*' || op=='^');
}

void Convert::to_Postfix(string infix, char postfix[])
{
    int position, outpos=0;
    char c;
    int count = 0;
    char temp;
    char stacktop ;
    Stack<char> stack;
    for(position = 0; (c = infix[position])!='\0'; position++)
    {
        if(this->isOperand)
        {
            postfix[outpos++] = c;
            this->num_flag = true;
            count++;
            if(count>=2)
            {
                this->tow_digit_flag = true;
            }
        }
        else if(this->isOperator©)
        {
            count = 0;
            if(isOperator(infix[position]) && isOperator(infix[position+1]))
            {
                cout<<"\aMissing argument in between "<<infix[position]<<" and "<<infix[position+1]
                    <<" in column "<< position+1<<endl;
                exit(9);
            }
            if(this->prcd(c, stacktop))
            {
                stacktop=stack.return_top();
                stack.push©;
                stacktop = c;
            }
            else
            {
                while(true)
                {
                    temp = stack.pop();
                    postfix[outpos++] =temp;
                    stacktop = stack.return_top();
                    if(prcd(c, stacktop) || stacktop=='(')
                        break;
                }
                stack.push©;
                stacktop = stack.return_top();
            }
        }
        else if(c=='(')
        {
            count = 0;
            stack.push©;
            stacktop = stack.return_top();
        }
        else if(c==')')
        {
            count = 0;
            while(1)
            {
                if(stack.size()==0)
                {
                    cout<<"Warning!! Number of ')' is greater than '('" <<endl;
                    exit(2);
                }
                temp = stack.pop();
                if(temp!='(')
                {
                    postfix[outpos++] = temp;
                }
                else
                {
                    break;
                }
            }
            stacktop =stack.return_top();
        }
        else
        {
            cout<<"Invalid input";
            exit(3);
        }
        if(infix[position]==')' && infix[position+1]=='(')
        {
            stack.push('*');
            stacktop = stack.return_top();
        }
    }
    if(stack.size()!=0)
    {
        cout<<"Warning!!Number of '(' is greater than ')'"<<endl;
        // exit(6);
    }
    if(!this->return_flag())
    {
        cout<<"You must Enter Numeric value for calculation"<<endl;
        cout<<"This program cannot perform operations on variables";
        exit(5);
    }
    if(this->tow_digit_flag)
    {
        cout<<"Sory! Althoug u may have entered right string"<<endl;
        cout<<"this program is only for single digit operation"<<endl;
        exit(8);
    }
    postfix[outpos] = '\0';
}

class Evaluate
{
public:
    double eval(char expr[], Convert &Wink;
                double oper(int symb, double op1, double op2);
};
double Evaluate::oper(int symb, double op1, double op2)
{
    switch(symb)
    {
    case '+':
        return (op1 + op2);
    case '-':
        return (op1 - op2);
    case '*':
        return (op1 * op2);
    case '/':
        return (op1 / op2);
    case '^':
        return (pow(op1, op2));
    }
}
double Evaluate::eval(char expr[],Convert &convert)
{
    int c, position;
    char temp1;
    int count = 0;
    double opnd1, opnd2, value;
    Stack<double> stack;
    for(position = 0; (c = expr[position])!='\0'; position++)
    {
        if(convert.isOperand©)
        {
            temp1 = double(c-'0');
            stack.push(temp1);
        }
        else
        {
            opnd2 = stack.pop();
            if(stack.size()==0)
            {
                cout<<"This program cannot process unary operation";
                exit(1);
            }
            opnd1 = stack.pop();
            value = oper(c, opnd1, opnd2);
            stack.push(value);
        }
    }
    if(stack.size()>=2)
    {
        cout<<"Sory! this program cannot calculate this"<<endl;
        cout<<"Enter +, *, /, - or ^ between bracket"<<endl;
        exit(4);
    }

    return (stack.pop());
}
int main()
{
    Convert convert;
    Evaluate evaluate;
    string bracketted_infix;
    char infix[50], postfix[50];
    char choice;
    while(1)
    {
        cout<<"Enter operation: ";
        cin>>infix;
        cout<<endl;
        cout<<"Entered operation: "<<infix<<endl;
        bracketted_infix = convert.return_with_bracket(infix);
        convert.to_Postfix(bracketted_infix, postfix);
        cout<<"Equivalent Postfix operation: "<<postfix<<endl;
        cout<<"RESULT: ";
        cout<<evaluate.eval(postfix, convert);
        cout<<"\nCalculate another operation?(y/n) ";
        cin>>choice;
        cout<<endl;
        if(choice=='n')
            break;
    }
    return 0;
}

Ответы [ 2 ]

2 голосов
/ 17 ноября 2011

Для его фактической компиляции необходимо исправить две синтаксические ошибки:

В строке 154 вы вызываете метод без параметра, но единственное объявление этого метода принимает 1 параметр.

if (this->isOperand) {

Полагаю, вы могли иметь в виду:

if (this->isOperand(c)) {

Также в строке 255 перед точкой с запятой пропущена скобка:

double eval(char expr[], Convert &Wink;

Когда я действительно запустил ваш код, это не удалосьво время выполнения VS2010 выдает ошибку «строковый индекс вне диапазона».

Если вы этого еще не сделали, я бы порекомендовал использовать хорошую IDE (например, Visual C ++) при разработке;раскраска синтаксиса и поддержка динамической отладки (то есть точки останова и наблюдения) были бы очень полезны для отладки такой программы.

1 голос
/ 17 ноября 2011

Вот окончательное решение

#include<iostream>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<string>

#define MAX_SIZE 20

using namespace std;
template<class T>
class Stack
{
private:
    T item[MAX_SIZE];
    int top;
public:
    Stack()
    {
        top = -1;
    }

    void push(T data)
    {
        if(!this->is_full())
            item[++top] = data;
        else
        {
            cout<<"Stack Error"<<endl;
            exit(10);
        }
    }
    T pop()
    {
        if(!this->is_empty())
            return item[top--];
        else
        {
            cout<<"Stack is Empty"<<endl;
            exit(11);
        }
    }

    int size()
    {
        return top+1;
    }

    bool is_empty()
    {
        if(top==-1)
            return true;
        else
            return false;
    }

    bool is_full()
    {
        if(top==MAX_SIZE-1)
            return true;
        else
            return false;
    }

    void display()
    {
        for(int i=0; i<this->size(); i++)
        {
            cout<<item[i]<<" ";
        }
        cout<<endl;
    }
    T return_top()
    {
        return item[top];
    }
};

class Convert
{
private:
    bool num_flag;
    bool tow_digit_flag;
public:
    Convert();
    string return_with_bracket(string infix);
    void to_Postfix(string infix,char postfix[]);
    bool prcd(char op1, char op2);
    int isOperand(char op);
    int isOperator(char op);
    bool return_flag()
    {
        return num_flag;
    }
};

Convert::Convert()
{
    this->num_flag = false;
    this->tow_digit_flag = false;
}
string Convert::return_with_bracket(string infix)
{
    return("(" + infix + ")");
}

bool Convert::prcd(char op1, char op2)
{
    if((op1=='+' || op1=='-' || op1=='*' || op1=='/') && op2=='(' )
        return true;
    if(op1=='+' && op2=='+')
        return true;
    if(op1=='-' && op2=='-')
        return false;
    if(op1=='-' && op2=='+')
        return false;
    if(op1=='+' && op2=='-')
        return false;
    if(op1=='/' && op2=='/')
        return false;
    if(op1=='/' && (op2=='-' || op2=='+'))
        return true;
    if(op1=='*' && (op2=='+' || op2=='-'))
        return true;
    if((op1 == '-' || op1 == '+') && (op2 =='*' || op2 == '/'))
        return false;
    if((op1=='$' || op1 == '+') && (op2 =='*' || op2 == '/' || op2=='-'))
        return true;
    if((op1 == '-' || op1 == '+' || op1 =='*' || op1 == '/')&& op2=='^')
        return false;
    if(op1 == '^' && ( op2 == '+' || op2 =='*' || op2 == '/' || op2=='-'))
        return false;
}

int Convert::isOperand(char op)
{
    return(op>= '0' && op <= '9');
}

int Convert::isOperator(char op)
{
    return(op=='+' || op=='-' || op == '/' || op=='*' || op=='^');
}

void Convert::to_Postfix(string infix, char postfix[])
{
    int position, outpos=0;
    char c;
    int count = 0;
    char temp;
    char stacktop ;
    Stack<char> stack;
    for(position = 0; (c = infix[position])!='\0'; position++)
    {
     if (this->isOperand(c)) 

        {
            postfix[outpos++] = c;
            this->num_flag = true;
            count++;
            if(count>=2)
            {
                this->tow_digit_flag = true;
            }
        }
        else if(this->isOperator(c))
        {
            count = 0;
            if(isOperator(infix[position]) && isOperator(infix[position+1]))
            {
                cout<<"\aMissing argument in between "<<infix[position]<<" and "<<infix[position+1]
                    <<" in column "<< position+1<<endl;
                exit(9);
            }
            if(this->prcd(c, stacktop))
            {
                stacktop=stack.return_top();
                stack.push(c);
                stacktop = c;
            }
            else
            {
                while(true)
                {
                    temp = stack.pop();
                    postfix[outpos++] =temp;
                    stacktop = stack.return_top();
                    if(prcd(c, stacktop) || stacktop=='(')
                        break;
                }
                stack.push(c);
                stacktop = stack.return_top();
            }
        }
        else if(c=='(')
        {
            count = 0;
            stack.push(c);
            stacktop = stack.return_top();
        }
        else if(c==')')
        {
            count = 0;
            while(1)
            {
                if(stack.size()==0)
                {
                    cout<<"Warning!! Number of ')' is greater than '('" <<endl;
                    exit(2);
                }
                temp = stack.pop();
                if(temp!='(')
                {
                    postfix[outpos++] = temp;
                }
                else
                {
                    break;
                }
            }
            stacktop =stack.return_top();
        }
        else
        {
            cout<<"Invalid input";
            exit(3);
        }
        if(infix[position]==')' && infix[position+1]=='(')
        {
            stack.push('*');
            stacktop = stack.return_top();
        }
    }
    if(stack.size()!=0)
    {
        cout<<"Warning!!Number of '(' is greater than ')'"<<endl;
        // exit(6);
    }
    if(!this->return_flag())
    {
        cout<<"You must Enter Numeric value for calculation"<<endl;
        cout<<"This program cannot perform operations on variables";
        exit(5);
    }
    if(this->tow_digit_flag)
    {
        cout<<"Sory! Althoug u may have entered right string"<<endl;
        cout<<"this program is only for single digit operation"<<endl;
        exit(8);
    }
    postfix[outpos] = '\0';
}

class Evaluate
{
public:
    double eval(char expr[], Convert &Wink);
                double oper(int symb, double op1, double op2);
};
double Evaluate::oper(int symb, double op1, double op2)
{
    switch(symb)
    {
    case '+':
        return (op1 + op2);
    case '-':
        return (op1 - op2);
    case '*':
        return (op1 * op2);
    case '/':
        return (op1 / op2);
    case '^':
        return (pow(op1, op2));
    }
}
double Evaluate::eval(char expr[],Convert &convert)
{
    int c, position;
    char temp1;
    int count = 0;
    double opnd1, opnd2, value;
    Stack<double> stack;
    for(position = 0; (c = expr[position])!='\0'; position++)
    {
        if(convert.isOperand(c))
        {
            temp1 = char(c-'0');
            stack.push(temp1);
        }
        else
        {
            opnd2 = stack.pop();
            if(stack.size()==0)
            {
                cout<<"This program cannot process unary operation";
                exit(1);
            }
            opnd1 = stack.pop();
            value = oper(c, opnd1, opnd2);
            stack.push(value);
        }
    }
    if(stack.size()>=2)
    {
        cout<<"Sory! this program cannot calculate this"<<endl;
        cout<<"Enter +, *, /, - or ^ between bracket"<<endl;
        exit(4);
    }

    return (stack.pop());
}
int main()
{
    Convert convert;
    Evaluate evaluate;
    string bracketted_infix;
    char infix[50], postfix[50];
    char choice;
    while(1)
    {
        cout<<"Enter operation: ";
        cin>>infix;
        cout<<endl;
        cout<<"Entered operation: "<<infix<<endl;
        bracketted_infix = convert.return_with_bracket(infix);
        convert.to_Postfix(bracketted_infix, postfix);
        cout<<"Equivalent Postfix operation: "<<postfix<<endl;
        cout<<"RESULT: ";
        cout<<evaluate.eval(postfix, convert);
        cout<<"\nCalculate another operation?(y/n) ";
        cin>>choice;
        cout<<endl;
        if(choice=='n')
            break;
    }
    return 0;
}
...