hdu2127Polish notation

嗨,这道题是个好题,既考了字符串操作函数,又考了栈的使用
遵循一个操作符旁边有两个操作数,用两个栈,一个操作符栈和一个操作数栈,模拟操作的出波兰式
代码要做的是:(利用运算符的优先级)
1、初始化一个操作符栈,一个操作数栈
2、反向开始,因为是求波兰式,如果遇到数字,将数字这段字符串进入操作数栈;如果操作符栈为空,直接将操作符入栈,遇到‘)’,直到遇到‘(’,将操作符栈中的操作符取出,每取出一个操作符,就从操作数栈中取出两个字符串,组合成新的字符串再次入操作数栈,(主要遵循一个操作符左右必有两个操作数或表达式);如果将要进入操作数栈的优先级大于里面的,直接入栈,如果小于栈里的操作符,则取出一个操作符,必取出两个操作数。
3、最后还是利用栈将表达式计算出来
还有一种方法是将表达式还原成二叉树,前序表达式就是所求,接下来写完会更新

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stack>
#include<queue>
#include<cstdlib>
#include<string>
#include<map>
using namespace std;
#define N 105
typedef long long LL;
map<char,int>mp;
map<char,string>mt;
const string sample = "+-*/()";
void Init()
{
    mp['+'] = 1;mp['-'] = 1;mp['*'] = 2;
    mp['/'] = 2;mp['('] = 0;mp[')'] = 0;
    mt['+'] = "+";mt['-'] = "-";
    mt['*'] = "*";mt['/'] = "/";
}
stack<string>num; //储存操作数
stack<char>opt;    //储存操作符
bool judge(char ch)
{
    return ch == '+' || ch == '-' || ch == '*' || ch == '/';
}
string getstring(string s)
{
    while(!num.empty()) num.pop();
    while(!opt.empty()) opt.pop();
    string newstring;
    for(int i = s.size() - 1;i >= 0;--i)
    {
        if(isdigit(s[i]))
        {
            int index = s.find_last_of(sample,i);
            string numstring = s.substr(index + 1,i - index);
            //cout << numstring << endl;
            num.push(numstring);
            i = index + 1;
        }
        else{
            if(s[i] == ')')
                opt.push(s[i]);
            else{
                if(!opt.empty() && s[i] == '(')
                {
                    while(opt.top() != ')')
                    {
                        char ptr = opt.top();
                        opt.pop();
                        string x = num.top();num.pop();
                        string y = num.top();num.pop();
                        string tmp = mt[ptr] + " " + x + " " + y;
                        //cout << tmp << endl;
                        num.push(tmp);
                    }
                    opt.pop();
                }
                else{
                    if(!opt.empty() && mp[s[i]] >= mp[opt.top()])
                        opt.push(s[i]);
                    else{
                        //cout << s[i] << " " << opt.top() << endl;
                        if(!opt.empty() && mp[s[i]] < mp[opt.top()])
                        {
                            while(!opt.empty() && mp[s[i]] < mp[opt.top()])
                            {
                                char ptr = opt.top();
                                opt.pop();
                                string x = num.top();num.pop();
                                string y = num.top();num.pop();
                                string tmp = mt[ptr] + " " + x + " " + y;
                            //cout << tmp << endl;
                                num.push(tmp);
                            }
                            opt.push(s[i]);
                        }
                        else{
                            if(opt.empty() && judge(s[i]))
                                opt.push(s[i]);
                        }
                    }
                }
            }
        }
    }
    while(!opt.empty())
    {
        char ptr = opt.top();
        opt.pop();
        string x = num.top();num.pop();
        string y = num.top();num.pop();
        string tmp = mt[ptr] + " " + x + " " + y;
        //cout << tmp << endl;
        num.push(tmp);
    }
    newstring = num.top();
    return newstring;
}
LL cal(string s)
{
    stack<LL>sta;
    for(int i = s.size() - 1;i >= 0;--i)
    {
        //if()
        if(isdigit(s[i]))
        {
            int index = s.find_last_of(' ',i);
            string tmp = s.substr(index + 1,i - index);
            LL n;
            sscanf(tmp.c_str(),"%lld",&n);
            sta.push(n);
            i = index + 1;
        }
        else{
            if(s[i] != ' ' && judge(s[i]))
            {
                LL n = sta.top();sta.pop();
                LL m = sta.top();sta.pop();
                switch(s[i])
                {
                    case '+':sta.push(n + m);break;
                    case '-':sta.push(n - m);break;
                    case '*':sta.push(n * m);break;
                    case '/':sta.push(n / m);break;
                }
            }
        }
    }
    return sta.top();
}
int main()
{
    /*string s = "456+*-/";
    cout << atoi(s.c_str()) << endl;*/
    string s;
    s = "456";
    //初始化操作符的优先级
    Init();
    int k = 0;
    //cout << judge('-') << endl;
    while(cin >> s)
    {
        k++;
        printf("Case %d:\n",k);
        string tmp = getstring(s);
        cout << tmp << endl;
        cout << cal(tmp) << endl;
    }
    return 0;
}

重建二叉树求解:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<map>
#include<cmath>
#include<stack>
using namespace std;
typedef struct Tree{
    int num;
    struct Tree *leftchild;
    struct Tree *rightchild;
}Tree,*Node;
typedef long long LL;
map<int,char>mp;
map<char,LL>mp1;
string sample = "+-*/()";
void Init()
{
    mp1['+'] = 101;  mp1['*'] = 201;
    mp1['-'] = -101; mp1['/'] = -201;
    mp1['('] = -1;   mp1[')'] = -2;
    mp[101] = '+';  mp[201] = '*';
    mp[-101] = '-'; mp[-201] = '/';
    mp[-1] = '(';   mp[-2] = ')';
}
LL a[50];
void solve(string s,int &k)
{
    k = 0;
    for(int i = 0;i < s.length();++i)
    {
        if(isdigit(s[i])){
            int index = s.find_first_of(sample,i);
            string tmp = s.substr(i,index - i);
            LL num;
            //cout << tmp << endl;
            sscanf(tmp.c_str(),"%lld",&num);
            //cout << num << endl;
            a[k++] = num;
            i = index - 1;
        }
        else{
            a[k++] = mp1[s[i]];
            //cout << mp1[s[i]] << " " << a[k - 1] << endl;
        }
    }
    /*for(int i = 0;i < k;++i)
        {
            printf("%lld ",a[i]);
        }*/
}
bool check(char ch)
{
    if(ch == '+' || ch == '-' || ch == '*' || ch == '/')
        return true;
    else
        return false;
}
Node createTree(LL *res,int start,int end)
{
    int test = 0;
    //去除空格
    bool flag = false;
    if(res[start] == mp1['(']){
        for(int i = start;i <= end;++i)
        {
            if(res[i] == mp1['('])
                test++;
            else{
                if(res[i] == mp1[')'])
                    test--;
                else{
                    if(test == 0 && i != end)
                       {
                           flag = true;
                           break;
                       }
                }
            }
        }
        if(!flag)
        {
            start++;
            end--;
        }
    }
    int num = 0;//num=0说明不在括号里面
    if(start == end){
        Node node = (Tree *)malloc(sizeof(Tree));
        node -> num = res[start];
        node -> leftchild = NULL;
        node -> rightchild = NULL;
        return node;
    }
    int tmp = 300;//优先级最小的运算符
    int ptr;
    for(int i = start;i <= end;++i)
    {
        if(res[i] == mp1['('])
           num++;
        else{
            if(res[i] == mp1[')'])
                num--;
            else{
                if(num == 0)
                {
                    if(abs(res[i]) > 100){
                        if(abs(res[i]) <= tmp){
                            tmp = abs(res[i]);
                            ptr = i;
                        }
                    }
                }
                else
                    continue;
            }
        }
    }
    Node node = (Tree *)malloc(sizeof(Tree));
    node -> num = res[ptr];
    node -> leftchild = createTree(res,start,ptr - 1);
    node -> rightchild = createTree(res,ptr + 1,end);
    return node;
}
LL b[50];
int x = 0;
void preorder(Node root)
{
    if(root)
    {
        b[x++] = root -> num;
        preorder(root -> leftchild);
        preorder(root -> rightchild);
    }
}
LL cal()
{
    stack<LL>sta;
    LL res;
    for(int i = x - 1;i >= 0;--i)
    {
        if(abs(b[i]) > 100)
        {
            LL c = sta.top();sta.pop();
            LL d = sta.top();sta.pop();
            switch(mp[b[i]])
            {
                case '+':res = c + d;break;
                case '-':res = c - d;break;
                case '*':res = c * d;break;
                case '/':res = c / d;break;
            }
            sta.push(res);
        }
        else{
            sta.push(b[i]);
        }
    }
    return sta.top();
}
int main()
{
    string s;
    Init();
    int k = 0;
    while(cin >> s)
    {
        k++;
        int len;
        solve(s,len);
        /*for(int i = 0;i < len;++i)
        {
            printf("%lld ",a[i]);
        }*/
        printf("Case %d:\n",k);
        Node root;
        root = createTree(a,0,len - 1);
        x = 0;
        preorder(root);
        for(int i = 0;i < x - 1;++i)
        {
            if(abs(b[i]) >= 100){
                cout << mp[b[i]] << " ";
            }
            else{
                cout << b[i] << " ";
            }
        }
        cout << b[x - 1] << endl;
        cout << cal() << endl;
    }
    return 0;
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值