首页 新闻 会员 周边

数据结构c++表达式计算

0
悬赏园豆:40 [已解决问题] 解决于 2021-11-16 16:22

想让大家帮我看看我的代码哪里错了,谢谢了
题目:
表达式计算
Time Limit: 1000 MS Memory Limit: 1000 KB

Description

输入一串表达式,计算其结果。表达式包括数字'0'~'9'、'+'、'-'、'*'、'/'、'('、')',并以符号'#'结尾。
在计算中,除法以向下取整计算。
保证表达式合法,且结果不超过long long范围。

Input

输入的第一行是一个int型整数T,表示一个有T组数据。
接下来T行,每行一个一个表达式。

Output

输出T行,每行一个整数,表示求得的结果。

Sample Input

2
1-2#
3*(1+2)#

Sample Output

-1
9

我的代码如下(其中中缀转后缀的地方是完全正确的,后缀计算那里有些问题,提交后显示runtime error):

#include <iostream>
#include <string>
#include <stack>

using namespace std;

//操作符的栈内、外优先级
int isp(char x)//栈内
{
    if (x == '*' || x == '/') return 5;
    if (x == '+' || x == '-') return 3;
    if (x == '(') return 1;
    else return -1;
}
int icp(char x)//栈外
{
    if (x == '*' || x == '/') return 4;
    if (x == '+' || x == '-') return 2;
    if (x == '(') return 6;
    else return -1;
}

int main()
{
    string infix, postfix;
    stack<char> operators;
    int T;
    cin >> T;
    char ch;
    for (int q = 0; q < T; ++q)
    {
        cin >> infix;
        for (int i = 0; infix[i] != '#'; i++)
        {
            ch = infix[i];
            if (ch >= '0' && ch <= '9')
            {//是操作数,输出
                postfix.push_back(ch);
            }
            else if (operators.empty())
            {//若是空的,让该操作符进栈
                operators.push(ch);
            }
            else if (ch == ')')
            {
                while (operators.top() != '(' && !operators.empty())
                {
                    postfix.push_back(operators.top());
                    operators.pop();
                }
                operators.pop();
            }
            else if (ch == '(')
            {
                operators.push(ch);
            }
            else if (ch == '+' || ch == '-'
                || ch == '*' || ch == '/')
            {//是加减乘除
                while (isp(operators.top()) >= icp(ch))
                {
                    postfix.push_back(operators.top());
                    operators.pop();
                    if (operators.empty())
                    {
                        break;
                    }
                }
                operators.push(ch);
            }
        }
        while (!operators.empty())
        {
            postfix.push_back(operators.top());
            operators.pop();
        }
        //储存数字
        stack<long long int> re;
        //开始进行计算
        char op;
        for (int y = 0; y < postfix.size(); ++y)
        {
            op = postfix[y];
            if (op >= '0' && op <= '9')
            {
                int l = op - '0';
                re.push(l);
            }
            else
            {
                //出栈顶两个数字
                long long int a = re.top();
                re.pop();
                long long int b = re.top();
                re.pop();
                if (op == '+')
                {//加
                    re.push(a + b);
                }
                else if (op == '-')
                {//减
                    re.push(b - a);
                }
                else if (op == '*')
                {//乘
                    re.push(a * b);
                }
                else if (op == '/')
                {//除
                    re.push(b / a);
                }
            }
        }
        long long int result = re.top();
        cout << result << endl;
        infix.clear();
        postfix.clear();
    }
    return 0;
}
流云轻响的主页 流云轻响 | 初学一级 | 园豆:168
提问于:2021-10-19 19:29
< >
分享
最佳答案
0

今天又看了看这道题,解决了,原因是计算的时候,我原以为都是一位的数(即没有1+87这种的),现支持了多位数的运算。我的思路是在后缀表达式的两个数字之间用“.”来分隔开。
代码如下:

#include <iostream>
#include <string>
#include <stack>

using namespace std;

//操作符的栈内、外优先级
int isp(char x)//栈内
{
    if (x == '*' || x == '/') return 5;
    if (x == '+' || x == '-') return 3;
    if (x == '(') return 1;
    else return -1;
}
int icp(char x)//栈外
{
    if (x == '*' || x == '/') return 4;
    if (x == '+' || x == '-') return 2;
    if (x == '(') return 6;
    else return -1;
}

int main()
{
    //postfix的存储中,一个数字结束 用.来表示
    string infix, postfix;
    stack<char> operators;
    int T;
    cin >> T;
    char ch;
    for (int q = 0; q < T; ++q)
    {
        cin >> infix;
        for (int i = 0; infix[i] != '#'; i++)
        {
            ch = infix[i];
            if (ch >= '0' && ch <= '9')
            {//是操作数,输出
                postfix.push_back(ch);
            }
            else if (operators.empty())
            {//若是空的,让该操作符进栈
                operators.push(ch);
                postfix.push_back('.');
            }
            else if (ch == ')')
            {
                while (operators.top() != '(' && !operators.empty())
                {
                    postfix.push_back('.');
                    postfix.push_back(operators.top());
                    operators.pop();
                }
                operators.pop();
            }
            else if (ch == '(')
            {
                postfix.push_back('.');
                operators.push(ch);
            }
            else if (ch == '+' || ch == '-'
                || ch == '*' || ch == '/')
            {//是加减乘除
                postfix.push_back('.');
                while (isp(operators.top()) >= icp(ch))
                {
                    postfix.push_back(operators.top());
                    operators.pop();
                    if (operators.empty())
                    {
                        break;
                    }
                }
                operators.push(ch);
            }
        }
        while (!operators.empty())
        {
            postfix.push_back(operators.top());
            operators.pop();
        }
        //储存数字
        stack<long long int> re;
        //re顶的数字与正在读的数字是否属于一个数字
        bool iN = true;
        //开始进行计算
        char op;
        for (int y = 0; y < postfix.size(); ++y)
        {
            op = postfix[y];
            if ((op >= '0' && op <= '9'))
            {
                int l = op - '0';
                if (iN == true)
                {//是新的数字,直接入栈
                    re.push(l);
                    iN = false;
                }
                else
                {//不是新的数字
                    l += re.top() * 10;
                    re.pop();
                    re.push(l);
                }
            }
            else if (op == '.')
            {//前一个数字结束
                iN = true;
            }
            else
            {
                //出栈顶两个数字
                long long int a = re.top();
                re.pop();
                long long int b = re.top();
                re.pop();
                if (op == '+')
                {//加
                    re.push(a + b);
                    iN = true;
                }
                else if (op == '-')
                {//减
                    re.push(b - a);
                    iN = true;
                }
                else if (op == '*')
                {//乘
                    re.push(a * b);
                    iN = true;
                }
                else if (op == '/')
                {//除
                    re.push(b / a);
                    iN = true;
                }
            }
        }
        long long int result = re.top();
        cout << result << endl;
        infix.clear();
        postfix.clear();
    }
    return 0;
}
流云轻响 | 初学一级 |园豆:168 | 2021-11-16 16:20

Good work!

blogger2020 | 园豆:257 (菜鸟二级) | 2021-11-25 09:48
其他回答(2)
1

I had following issues on your code.
1.#include <iostream> added
2.warning: comparison of integer expressions of different signedness: ‘int’ and ‘std::__cxx11::basic_string<char>::size_type’ {aka ‘long unsigned int’} [-Wsign-compare]
81 | for (int y = 0; y < postfix.size(); ++y)
|
I changed to: for (int y = 0; y < (int)postfix.size(); ++y) - if that is OK with you.
3. After above fixing, compiler worked:
g++ expression.cpp -o exp -Wall
4. running your code on ubuntu20
I had following:
Test1: worked:
ora01@ubuntu20:~/projects/test$ ./exp
2
1-2#
-1
3*(1+2)#
9

Test2: failed:
ora01@ubuntu20:~/projects/test$ ./exp
2
12+(3+9)-3#
11
5+4
3-220/20
Segmentation fault (core dumped)
Remarks: You might want to add check on each line with '#'.
If '#' is not found, you might want to consider the input line is not valid.

Test3: failed
ora01@ubuntu20:~/projects/test$ ./exp
2
12+37-3#
20
5+3*2-220/20#
Floating point exception (core dumped)
Remarks:
It may have issues on calculation.

Hope this helps.
And let us know if you have any further issue please, if possible.
Thanks,

收获园豆:20
blogger2020 | 园豆:257 (菜鸟二级) | 2021-10-19 20:00

First of all, thank you very much for your answer.
Sorry about the first one, I missed a line when I copied. It has now been corrected in the question.
On the second issue, although I don't understand what you're trying to do, it didn't work.

支持(0) 反对(0) 流云轻响 | 园豆:168 (初学一级) | 2021-10-19 20:27
1

runtime error是指运行时错误吧,应该是数组越界或者类似的错误

收获园豆:20
计算机知识杂谈 | 园豆:470 (菜鸟二级) | 2021-10-19 20:48

谢谢你,我再努力找找哪错了

支持(0) 反对(0) 流云轻响 | 园豆:168 (初学一级) | 2021-10-20 11:04
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册