【问题标题】:Binary Operads sample program二元运算示例程序
【发布时间】:2011-12-31 02:49:02
【问题描述】:

问题陈述: 编写一个 C++ 程序来计算后缀表达式。您的程序应将后缀表达式作为输入,在堆栈的帮助下对其进行处理,并在执行所需的计算后显示结果。

此程序只允许使用以下二元运算符: +, -, *, /, ^ [加减乘除求幂]

如果在处理后缀表达式时发生错误,您的程序应该显示一条有意义的消息,例如: 错误:不允许除以零 错误:__ 运算符需要两个操作数 错误:后缀表达式无效

帮帮我,我的程序出现错误这是我的尝试:

#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;
}

【问题讨论】:

  • 你遇到了什么错误?
  • 你能发布你得到的错误吗?
  • 您在文字处理应用程序中编程? (c) 变成 ©...
  • 你能发布一个有问题的小程序吗?它甚至可以帮助您自己发现问题。 sscce.org
  • 尝试使用std::stack。 msdn.microsoft.com/en-us/library/56fa1zk5%28v=vs.71%29.aspx 而不是编写自己的课程。至少它会简化你的调试。

标签: c++ stack postfix-notation rpn


【解决方案1】:

要让它真正编译,你需要修复两个语法错误;

在第 154 行,您正在调用一个没有参数的方法, 但此方法的唯一声明需要 1 个参数。

if (this->isOperand) {

我相信你的意思可能是:

if (this->isOperand(c)) {

同样在第 255 行,分号前缺少括号:

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

当我实际运行您的代码时,它在运行时失败,VS2010 给出错误“字符串下标超出范围”。

如果您还没有,我建议您在开发时使用好的 IDE(例如 Visual C++);语法着色和对动态调试(即断点和监视)的支持对于调试这样的程序非常有帮助。

【讨论】:

    【解决方案2】:

    这是最终的解决方案

    #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;
    }
    

    【讨论】:

      猜你喜欢
      • 2016-03-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-11
      • 1970-01-01
      相关资源
      最近更新 更多