• 堆栈入门-简单计算器模板-中缀转后缀


    题目链接

    后缀表达式又称逆波兰表示法,不含括号,运算符放在两个参与运算的语法成分的后面。

    后缀表达式运算求值

    自左向右顺序扫描后缀表达式。最后栈中的数字就是答案。

    (1)如果是数字,则压入栈中。

    (2)如果是运算符,就从栈中弹出两个数字进行运算,将运算结果压入栈中。

    中缀表达式转后缀表达式

    从左向右扫描中缀表达式。

    (1)当输入为数字时,直接输出到后续表达式序列中。

    (2)当遇到开括号时,将其入栈。(代表一个子域)

    (3)当遇到闭括号时,先判断栈是否为空,若为空,则表示括号不匹配,报告异常并退出。若非空,则将栈中元素依次弹出,直到遇到第一个开括号为止(将开括号也弹出)。将弹出的元素输出到后缀表达式序列中。若没有遇到开括号,则报告异常并退出。

    (4)当输入为运算符时(四则运算+ - * /之一)

    • (栈非空&&栈顶运算符的优先级不低于输入运算符的优先级&&栈顶不是开括号时,循环,反复操作将栈顶元素弹出,放入后缀表达式序列。(优先级即相当于更小的子域,循环将小子域排干净)
    • 将输入的运算符压入栈内。

    (5)中缀表达式全部扫描完毕,清栈,全部弹出放入后缀表达式序列中。若弹出元素中有开括号,报告异常并退出。

    模板-中缀表达式转后缀表达式

    注意:这个模板提醒了我一个有意思的点。char[]={0}就是在结尾加上了换行符,int[]={1}仅仅是将首元素变为1,其余为0,如果int[]则默认所有元素为0。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<stack>
    using namespace std;
    
    int priority(char c)
    {
        if (c == '+' || c == '-')return 0;
        else if (c == '*' || c == '/')return 1;
    }
    
    int main()
    {
        char in[205];
        char post[205] = { 0 };
        stack<char> s;
        scanf("%s", in);
        int l = strlen(in);
        int size = 0;
        for (int i = 0; i < l; i++)
        {
            if (in[i] >= 'a'&&in[i] <= 'z')post[size++] = in[i];
            else if (in[i] == '(')s.push(in[i]);
            else if (in[i] == ')')
            {
                if (s.empty())
                {
                    printf("Wrong!
    ");
                    return 0;
                }
                while (s.top() != '(' && !s.empty())
                {
                    post[size++] = s.top();
                    s.pop();
                }
                if (s.empty())printf("Wrong!
    ");
                else s.pop();
            }
            else if (in[i] == '*' || in[i] == '/' || in[i] == '+' || in[i] == '-')
            {
                while (!s.empty() && priority(s.top()) >= priority(in[i]) && s.top() != '(')
                {
                    post[size++] = s.top();
                    s.pop();
                }
                s.push(in[i]);
            }
        }
        while (!s.empty())
        {
            post[size++] = s.top();
            s.pop();
        }
        printf("%s
    ", post);
        system("pause");
        return 0;
    }

    简单计算器题解(北理工10年第二题)

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<stack>
    using namespace std;
    
    int priority(char c)
    {
        if (c == '+' || c == '-')return 0;
        else if (c == '*' || c == '/')return 1;
    }
    
    int main()
    {
        char in[205];
        char post[205] = { 0 };
        stack<char> s;
        scanf("%s", in);
        int l = strlen(in);
        int size = 0;
        for (int i = 0; i < l; i++)
        {
            if (in[i] >= '0'&&in[i] <= '9')post[size++] = in[i];
            else if (in[i] == '(')s.push(in[i]);
            else if (in[i] == ')')
            {
                if (s.empty())
                {
                    printf("Wrong!
    ");
                    return 0;
                }
                while (s.top() != '(' && !s.empty())
                {
                    post[size++] = s.top();
                    s.pop();
                }
                if (s.empty())printf("Wrong!
    ");
                else s.pop();
            }
            else if (in[i] == '*' || in[i] == '/' || in[i] == '+' || in[i] == '-')
            {
                while (!s.empty() && priority(s.top()) >= priority(in[i]) && s.top() != '(')
                {
                    post[size++] = s.top();
                    s.pop();
                }
                s.push(in[i]);
            }
        }
        while(!s.empty())
        {
            post[size++] = s.top();
            s.pop();
        }
        cout << post << endl;
        stack<int> ans;
        for (int i = 0; i < size; i++)
        {
            if (post[i] >= '0'&&post[i] <= '9')ans.push(post[i] - '0');
            else
            {
                int b = ans.top(); ans.pop();
                int a = ans.top(); ans.pop();
                int c;
                if (post[i] == '+')c = a + b;
                else if (post[i] == '-')c = a - b;
                else if (post[i] == '*')c = a * b;
                else if (post[i] == '/')c = a / b;
                ans.push(c);
            }
        }
        printf("%d
    ", ans.top());
        system("pause");
        return 0;
    }

     后缀表达式转二叉树及前序遍历得到前缀表达式

    知识链接    知识链接

    将后缀表达式转化成二叉树:

    首先准备一个二叉树节点栈s.

    1、从左开始向右遍历逆波兰式的元素。

    2、每遍历一个元素都新建一个树节点p,char值为当前字符(不管是操作数还是运算符)。

    如果取到的元素是操作数,直接把p入栈s;

    如果是运算符,从栈中弹出2个节点,把第一个弹出的节点作为p的右子树,第二个弹出的节点作为p的左子树,然后把p入栈。

    当遍历完逆波兰式时,树的根节点就保存在栈里了。

    例:输入:a+b*(c-d)-e/f   输出:-+a*b-cd/ef  (北理工13年第三题)

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<stack>
    using namespace std;
    
    struct Node
    {
        Node* l;
        Node* r;
        char c;
    }t[50];
    
    int loc = 0;
    
    Node* create()
    {
        t[loc].l = t[loc].r = NULL;
        return &t[loc++];
    }
    
    void preorder(Node* t)
    {
        cout << t->c;
        if (t->l != NULL)preorder(t->l);
        if (t->r != NULL)preorder(t->r);
    }
    
    int priority(char c)
    {
        if (c == '+' || c == '-')return 0;
        else if (c == '*' || c == '/')return 1;
    }
    
    int main()
    {
        char in[205];
        char post[205] = { 0 };
        stack<char> s;
        scanf("%s", in);
        int l = strlen(in);
        int size = 0;
        for (int i = 0; i < l; i++)
        {
            if (in[i] >= 'a'&&in[i] <= 'z')post[size++] = in[i];
            else if (in[i] == '(')s.push(in[i]);
            else if (in[i] == ')')
            {
                if (s.empty())
                {
                    printf("Wrong!
    ");
                    return 0;
                }
                while (s.top() != '(' && !s.empty())
                {
                    post[size++] = s.top();
                    s.pop();
                }
                if (s.empty())printf("Wrong!
    ");
                else s.pop();
            }
            else if (in[i] == '*' || in[i] == '/' || in[i] == '+' || in[i] == '-')
            {
                while (!s.empty() && priority(s.top()) >= priority(in[i]) && s.top() != '(')
                {
                    post[size++] = s.top();
                    s.pop();
                }
                s.push(in[i]);
            }
        }
        while(!s.empty())
        {
            post[size++] = s.top();
            s.pop();
        }
        stack<Node*>tr;
        for (int i = 0; i < size; i++)
        {
            Node* n = create();
            n->c = post[i];
            if (n->c >= 'a'&&n->c <= 'z')tr.push(n);
            else if (n->c == '*' || n->c == '/' || n->c == '+' || n->c == '-')
            {
                Node* a = tr.top(); tr.pop();
                Node* b = tr.top(); tr.pop();
                n->r = a; n->l = b;
                tr.push(n);
            }
        }
        Node* root = tr.top();
        preorder(root);
        cout << endl;
        return 0;
    }
  • 相关阅读:
    南阳理工ACM1076--方案数量
    南阳理工oj88--汉诺塔(一)
    杭电ACM1170--Balloon Comes!
    杭电ACM2011-- 多项式求和
    杭电ACM2080--夹角有多大II
    杭电ACM2076--夹角有多大(题目已修改,注意读题)
    请!继续!
    南阳理工ACM954--N!
    南阳理工ACM975--关于521
    致自己即将到来的人生
  • 原文地址:https://www.cnblogs.com/yun-an/p/11357212.html
Copyright © 2020-2023  润新知