Evaluate expression in infix notation using stack

Em đang có 1 bài tập:

Code chạy nhưng ko đúng, em ko biết sai ở đâu nữa, mong mọi người xem giúp em ạ! em cảm ơn ạ!

Bài làm (link online):

#include <stdio.h>
#include <cstdlib>
#include<iostream>
#include<cctype>
#include<cstring>
#include<stack>
#include<cmath>
#include<sstream>
using namespace std;

class DividedByZero: public exception {};

bool is_balanced(const string& parenthesis) // for checking parentheses 
{
    stack<char> store;
    char check;
    for(string::size_type i = 0; i < parenthesis.length(); ++i)
    {
        check = parenthesis[i];
        if(check == '(' || check == '{' || check == '[')
        {
            store.push(check);
        }
        if(!store.empty())
        {
            if(check == ')')
            {
                if(store.top() == '(')
                {
                    store.pop();
                    continue;               
                }
                else
                {
                    break;
                }            
            }
            if(check == '}')
            {
                if(store.top() == '{')
                {
                     store.pop();
                     continue;
                }
                else
                {
                    break;
                }
            }
            if(check == ']')
            {
                if(store.top() == '[')
                {
                     store.pop();
                     continue;
                }
                else
                {
                    break;
                }
            }
        }
        else
            break;
    }   
    return(store.empty());
}

double precedence(char op) // precedence rules of operators
{
    if(op == '+' || op == '-')
        return 1;
    else if(op == '*' || op == '/')
        return 2;
   return 0;        
}

void parse_stack_top(stack<double>& operand, stack<char>& operation) // parse stack top
{
    double number1, number2;
    
    number2 = operand.top();
    operand.pop();
    
    number1 = operand.top();
    operand.pop();
    
    switch(operation.top())
    {
        case '+': operand.push(number1 + number2);
        break;
        
        case '-': operand.push(number1 - number2);
        break;
        
        case '*': operand.push(number1 * number2);
        break;
        
        case '/': 
        if(number2 == 0) // if number2 = 0, can not devide by zero
        {
            cout << "\nError!: Divide by zero.";       
            throw DividedByZero();
        }
        else
            operand.push(number1 / number2);
    }
    operand.pop();
}

double evaluate_stack(const string& token) // evaluate expression
{
    stack<double> operand;
    stack<char> operation;

    for(string::size_type i = 0; i < token.size(); i++)
    {
        if(isdigit(token[i]) || token[i] == '.') // check for numberic, and double value
        {
            double val;
            while(i < token.size() && isdigit(token[i])) // if element of number is larger than one
            {
                val = (val*10) + (token[i]-'0');
                i++;
            }
            i--;          
            operand.push(val);
        }       
        else if(token[i] == '+' || token[i] == '-' || token[i] == '*' || token[i] == '/')
        {
            while(!operation.empty() && precedence(token[i]) < precedence(operation.top()))
            {
                parse_stack_top(operand, operation);
                
            }
            operation.push(token[i]);
        }       
        else if(token[i] == '(' || token[i] == '{' || token[i] == '[')
        {
            operation.push('(');
        }
        
        else if(token[i] == ')' || token[i] == '}' || token[i] == ']')
        {
            while(!operation.empty() && operation.top() != '(' || operation.top() != '{' || operation.top() != '[')
            {
               parse_stack_top(operand, operation);            
            }
            operation.pop();
        }
    }       
    while(!operation.empty())
    {
         parse_stack_top(operand, operation);
    }  
    return operand.top();       
}

int main(int argc, char** argv) {

    string token;
    
    cout << "\nYour Expression: ";
    getline(cin, token);
    
    if(is_balanced(token))
    {
        answer = evaluate_stack(token);
        cout << "\nResult: " << answer;
        
    }
    else
        cout << "\nError!: parentheses is not balanced!";
    
    
    return 0;
}

merged to the #1 post by SITUVN.gcd

these lines have been added by noname00 :grin:

bài này mai là deadline, bí quá nên em mới mang lên đây để nhờ mg ạ :frowning:

Trong hàm evaluate_stack() thì cái này không đúng với số thực.

Nó chỉ lấy đến dấu . là hết. Rồi lại push lại ký tự trước dấu . mãi cho đến khi chết máy. :kissing:

4 Likes

vây em phải sửa đoạn nào ạ?

Mình sửa sương sương giúp bạn nè. :slight_smile:

#include <cctype>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <sstream>
#include <stack>
#include <stdio.h>

using namespace std;

class DividedByZero : public exception {};

bool is_balanced(const string &parenthesis) // for checking parentheses
{
    stack<char> store;
    char check;
    for (string::size_type i = 0; i < parenthesis.length(); ++i) {
        check = parenthesis[i];
        if (check == '(' || check == '{' || check == '[') { store.push(check); }
        if (!store.empty()) {
            if (check == ')') {
                if (store.top() == '(') {
                    store.pop();
                    continue;
                } else {
                    break;
                }
            }
            if (check == '}') {
                if (store.top() == '{') {
                    store.pop();
                    continue;
                } else {
                    break;
                }
            }
            if (check == ']') {
                if (store.top() == '[') {
                    store.pop();
                    continue;
                } else {
                    break;
                }
            }
        } else
            break;
    }
    return (store.empty());
}

double precedence(char op) // precedence rules of operators
{
    if (op == '+' || op == '-')
        return 1;
    else if (op == '*' || op == '/')
        return 2;
    return 0;
}

void parse_stack_top(stack<double> &operand, stack<char> &operation) // parse stack top
{
    double number1, number2;

    number2 = operand.top();
    operand.pop();

    number1 = operand.top();
    operand.pop();

    switch (operation.top()) {
    case '+': operand.push(number1 + number2); break;

    case '-': operand.push(number1 - number2); break;

    case '*': operand.push(number1 * number2); break;

    case '/':
        if (number2 == 0) // if number2 = 0, can not devide by zero
        {
            cout << "\nError!: Divide by zero.";
            throw DividedByZero();
        } else
            operand.push(number1 / number2);
    }
    operation.pop();
}

double evaluate_stack(const string &token) // evaluate expression
{
    stack<double> operand;
    stack<char> operation;

    for (string::size_type i = 0; i < token.size(); i++) {
        if (isdigit(token[i]) || token[i] == '.') // check for numberic, and double value
        {
            double val = 0;
            while (i < token.size() && isdigit(token[i])) // if element of number is larger than one
            {
                val = (val * 10) + (token[i] - '0');
                i++;
            }
            if (token[i] == '.') {
                double resp = 0;
                i++;
                int powTen = 10;
                while (i < token.size() && isdigit(token[i])) {
                    resp = resp + double(token[i] - '0') / powTen;
                    powTen *= 10;
                    i++;
                }
                val += resp;
            }
            if (!isdigit(token[i])) i--;
            operand.push(val);
        } else if (token[i] == '+' || token[i] == '-' || token[i] == '*' || token[i] == '/') {
            while (!operation.empty() &&  precedence(token[i]) < precedence(operation.top())) {
                parse_stack_top(operand, operation);
            }
            operation.push(token[i]);
        } else if (token[i] == '(' || token[i] == '{' || token[i] == '[') {
            operation.push('(');
        }

        else if (token[i] == ')' || token[i] == '}' || token[i] == ']') {
            while (!operation.empty() && operation.top() != '(') {
                parse_stack_top(operand, operation);
            }
            operation.pop();
        }
    }
    while (!operation.empty()) { parse_stack_top(operand, operation); }
    return operand.top();
}

int main(int argc, char **argv) {

    string token;

    cout << "\nYour Expression: ";
    getline(cin, token);

    if (is_balanced(token)) {
        cout << "\nResult: " << evaluate_stack(token);

    } else
        cout << "\nError!: parentheses is not balanced!";


    return 0;
}
2 Likes

em cảm ơn anh vì đã sửa cho em ạ! nhưng em run mà nó vẫn ko ra kết quả ạ :(((

cũng ko hiểu sai ở đâu nữa ạ :((

Được mà nhỉ. :thinking:

Bạn copy nguyên cả chỗ đó nha. :slight_smile:

:point_right: Test result

4 Likes

uầy, code chạy rùi ạ!! em cảm ơn anh nhìu nha anh <3 :smile:

83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?