• 自己yy的中缀表达式转后缀表达式(未验证完全正确)


    目前自己测试的表达式都没有出过问题

    思路是这样,先将后缀表达式的计算顺序搞出来。。当完全缩出来一个数的时候,如果后面还有要计算的,我们就把它放到后缀表达式的后面

    先算后面的。。不断迭代。。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    typedef long long ll;
    char sign[]={'+','-','*','/','^','(',')'},opSt[1000007],s[1000007];
    ll numSt[1000007];
    int opTail,numTail;
    bool is_sign(char x){
        int i;
        for(i=0;i<7;++i) if(x==sign[i]) return true;return false;
    }
    ll calc(ll a,ll b,char x){
        int i;
        for(i=0;i<5;++i){
            if(x==sign[i]){
                if(x=='+'){
                    return a+b;
                }
                else if(x=='-'){
                    return a-b;
                }
                else if(x=='*'){
                    return a*b;
                }
                else if(x=='/'){
                    return a/b;//这里是下取整,小心除以0
                    //除法的顺序
                }
                else if(x=='^'){
                    return a^b;
                }
            }
        }
        printf("unknown-op->err!
    ");//很关键
    }
    void printStack(){
        printf("numStack::
    ");
        for(int i=numTail-1;i>=0;--i) printf("%I64d
    ",numSt[i]);
        if(!numTail) printf("empty
    ");
        printf("opStack::
    ");
        for(int i=opTail-1;i>=0;--i) printf("%c
    ",opSt[i]);
        if(!opTail) printf("empty
    ");
    }
    int prev_q[1000007],back_q[1000007],pt,bt,seg_cnt,temp[1000007],tmp_cnt;
    bool is_res[1000007],is_char[1000007],IS_CHAR[1000007],TMP_CHAR[1000007];
    int ans[1000007],cnt;
    char str[1000007];int Next[1000007],Prev[1000007];
    void printBackStr(){
        printf("BackStr::
    ");
        for(int i=pt-1;i>=0;--i) printf("%d
    ",prev_q[i]);
        printf("=====
    ");
        for(int i=0;i<bt;++i) {
            if(is_char[i])     printf("%c
    ",back_q[i]);
            else             printf("%d
    ",back_q[i]);
        } 
    }
    void printAns(){
        int i;
        printf("AnsStr::  cnt::%d
    ",cnt);
        for(i=0;i<cnt;++i) {
            if(IS_CHAR[i])     printf("%c",ans[i]);
            else             printf("%d",ans[i]);
        }
        printf("|
    ");
    }
    void init(){
        opTail=0,numTail=0;
        pt=0;bt=0;cnt=0;seg_cnt=0;
        memset(is_res,0,sizeof(is_res));
        memset(is_char,0,sizeof(is_char));
        memset(IS_CHAR,0,sizeof(IS_CHAR));
        memset(TMP_CHAR,0,sizeof(TMP_CHAR));
    }
    void pop_Stack(int x){
        
        if(!x) back_q[bt++]=numSt[numTail-1];
        while(numTail&&opTail&&opSt[opTail-1]!='('){
                if(numTail-2<0) printf("popStack-err!
    ");
                if(!is_res[numTail-2]) prev_q[pt++]=numSt[numTail-2];
                back_q[bt++]=opSt[opTail-1];is_char[bt-1]=true;
                is_res[numTail-1]=false;is_res[numTail-2]=false;
                ll b=numSt[--numTail],a=numSt[--numTail];
                a=calc(a,b,opSt[--opTail]);
                is_res[numTail]=true;
                numSt[numTail++]=a;
        }
        if(numTail==1&&is_res[numTail-1]){
            int i;
            tmp_cnt=0;
            seg_cnt++;
            memset(TMP_CHAR,0,sizeof(TMP_CHAR));
            for(i=0;i<cnt;++i) {
                temp[tmp_cnt++]=ans[i];
                if(IS_CHAR[i]) TMP_CHAR[tmp_cnt-1]=1;
            }
            memset(IS_CHAR,0,sizeof(IS_CHAR));
            cnt=0;
            for(i=pt-1;i>=0;--i)  ans[cnt++]=prev_q[i];
            for(i=0;i<bt;++i){
                ans[cnt++]=back_q[i];
                if(is_char[i]) IS_CHAR[cnt-1]=true;
            }
            if(seg_cnt>=2){
                if(is_char[bt-1]){
                    cnt--;IS_CHAR[cnt]=0;//这里忘记修改IS_CHAR,可能输出了退格字符!!
                    for(i=0;i<tmp_cnt;++i) {
                        ans[cnt++]=temp[i];
                        if(TMP_CHAR[i]) IS_CHAR[cnt-1]=true;
                    }
                    ans[cnt++]=back_q[bt-1];IS_CHAR[cnt-1]=true;
                }
                else{
                    printf("segment->Exception
    ");
                    for(i=0;i<tmp_cnt;++i) {
                        ans[cnt++]=temp[i];
                        if(TMP_CHAR[i]) IS_CHAR[cnt-1]=true;
                    }
                }
            }
            //清空队列
            pt=0;bt=0;
            memset(is_char,0,sizeof(is_char));
        }
    }
    
    int main(){
        while(~scanf("%s",s)){
            int len=strlen(s);
            int i,j;
            init();
            for(i=0;i<len;++i){
                if(is_sign(s[i])){
                    opSt[opTail++]=s[i];
                }
                else{
                    ll base=0;int prev_pos=i;
                    while(i<len&&!is_sign(s[i])){
                        base=base*10+(s[i]-'0');
                        i++;
                    }
                    i--;
                    numSt[numTail++]=base;
                    if(i==len-1||s[i+1]=='+'||s[i+1]=='-'||s[i+1]=='^'||s[i+1]==')'){
                        if(i+1<len&&s[i+1]==')'){
                            //右边是右括号的情况
                            pop_Stack(0);            
                            if(opTail&&opSt[opTail-1]=='(') --opTail;
                            if(i+2==len||i+2<len&&s[i+2]!='*'&&s[i+2]!='/'){//少了最后是括号的判断
                                pop_Stack(1);
                            }
                            i++;//去除右括号
                        }
                        else {
                            if(prev_pos>0&&s[prev_pos-1]!='('){
                                if(i==len-1){
                                    pop_Stack(0);
                                }
                                else if(s[i+1]=='^'){
                                    pop_Stack(0);
                                }
                                else if(s[i+1]=='+'||s[i+1]=='-'){
                                    if(s[prev_pos-1]!='^'){
                                        pop_Stack(0);
                                    }
                                }
                                else {
                                    printf("JUDGE ERR!
    ");
                                }
                            }
                        }
                    }
                }
            }
            printf("NORMAL_ANS::%I64d
    ",numSt[0]);
            int slen=0;
            //这里按所有数字不超过10考虑
            for(i=0;i<cnt;++i){
                if(IS_CHAR[i])     str[slen++]=ans[i];
                else             str[slen++]=ans[i]+'0'; 
            }
            numTail=0,opTail=0;
            for(i=0;i<slen;++i){
                Next[i]=i+1;
                Prev[i]=i-1;
            }
            Next[slen-1]=-1;
            //将str写成了s,命名混淆
            for(j=0;j!=-1;j=Next[j]){
                    if(!is_sign(str[j])){
                        int t=str[j]-'0';
                        printf("%d ",t);
                    }
                    else{
                        printf("%c ",str[j]);
                    }
            }
            printf("
    ");
            //在这里char类型自然溢出了。。如果结果太大的话
            for(i=0;i!=-1;i=Next[i]){
                if(is_sign(str[i])){
                    ll b=str[Prev[i]]-'0';
                    ll a=str[Prev[Prev[i]]]-'0';
                    a=calc(a,b,str[i]);
                    int NextPos=Next[i];
                    str[Prev[Prev[i]]]=a+'0';
                    Next[Prev[Prev[i]]]=NextPos;
                    if(NextPos!=-1)
                    Prev[NextPos]=Prev[Prev[i]];
                    // printf("a::%I64d b:%I64d Next:%d
    ",a,b,NextPos);
                    for(j=0;j!=-1;j=Next[j]){
                        if(j==0&&Next[j]==-1) {printf("%I64d",numSt[0]);continue;}
                        if(!is_sign(str[j])){
                            ll t=str[j]-'0';
                            printf("%I64d ",t);
                        }
                        else{
                            printf("%c ",str[j]);
                        }
                    }
                    printf("
    ");
                }
            }
            printf("%I64d
    ",numSt[0]);
        }
        return 0;
    }
  • 相关阅读:
    题目分享M
    题目分享L
    题目分享J
    题目分享I
    FarmCraft
    C++语言中一些可能会用到的函数及头文件
    最小生成树(Kruskal & Prim & Boruvka)
    线段树板子(懒惰标记)
    FarmCraft——树形DP+贪心
    tarjan算法板子
  • 原文地址:https://www.cnblogs.com/linkzijun/p/6574702.html
Copyright © 2020-2023  润新知