【华为OJ】四则运算

  • 题目:

  • 输入输出:

  • 自己写的代码,在本地编译可以通过,但是提交上去通不过:

#include<iostream>
#include<stack>
#include<cctype>
#include<string>
#include<cstdio>
#include<cstdlib>
using namespace std;
#define N_OPTR 13
typedef enum{ ADD, SUB, MUL, DIV, POW, FAC, L_P1, R_P1, L_P2, R_P2, L_P3, R_P3, EOE } operation1;
const char pri[N_OPTR][N_OPTR] = {
    /*-------------------当前运算符------------------------*/
    /*           +    -    *    /    ^    !    (    )    [    ]    {    }   \0        */
    /* + */     '>', '>', '<', '<', '<', '<', '<', '>', '<', '>', '<', '>', '>',
    /* - */     '>', '>', '<', '<', '<', '<', '<', '>', '<', '>', '<', '>', '>',
    /* 栈 * */  '>', '>', '>', '>', '<', '<', '<', '>', '<', '>', '<', '>', '>',
    /* 顶 / */  '>', '>', '>', '>', '<', '<', '<', '>', '<', '>', '<', '>', '>',
    /* 运 ^ */  '>', '>', '>', '>', '>', '<', '<', '>', '<', '>', '<', '>', '>',
    /* 算 ! */ '>', '>', '>', '>', '>', '>', ' ', '>', ' ', '>', ' ', '>', '>',
    /* 符 (  */ '<', '<', '<', '<', '<', '<', '<', '=', ' ', ' ', ' ', ' ', ' ',
    /* ) */     ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
    /* [ */     '<', '<', '<', '<', '<', '<', '<', ' ', '<', '=', ' ', ' ', ' ',
    /* ] */     ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
    /* { */     '<', '<', '<', '<', '<', '<', '<', ' ', '<', ' ', '<', '=', ' ',
    /* } */     ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
    /* \0 */    '<', '<', '<', '<', '<', '<', '<', ' ', '<', ' ', '<', ' ', '='
};
void readNumber(char*& p, stack<float>& stk){
    stk.push((float)(*p - '0'));
    while (isdigit(*(++p))){
        float k = stk.top();
        stk.pop();
        stk.push(k* 10 + (*p - '0'));
    }
    if (*p != '.')return;
    float fraction = 1;
    while (isdigit(*(++p))){
        float k = stk.top();
        stk.pop();
        stk.push(k + (*p - '0')*(fraction/=10));
    }
}
operation1 optr2rank(char op){
    switch (op){
    case '+':return ADD;
    case '-':return SUB;
    case '*':return MUL;
    case '/':return DIV;
    case '^':return POW;
    case '!':return FAC;
    case '(':return L_P1;
    case ')':return R_P1;
    case '[':return L_P2;
    case ']':return R_P2;
    case '{':return L_P3;
    case '}':return R_P3;
    case '\n':return EOE;
    default:exit(-1);
    }
}
float calcu(float pOpnd){
    if (pOpnd == 0)return 1;
    return pOpnd*calcu(pOpnd - 1);
}
float calcu(float pOpnd1, char op, float pOpnd2){
    switch (op){
    case '+':return pOpnd1 + pOpnd2; break;
    case '-':return pOpnd1 - pOpnd2; break;
    case '*':return pOpnd1*pOpnd2; break;
    case '/':if (!(pOpnd2 - 0 < 0.0000001 && pOpnd2 - 0 > -0.0000001)){ return pOpnd1 / pOpnd2; break; }
             else{ cout << "error" << endl; return 0; }
    case '^':
        float a = pOpnd1;
        while (1<pOpnd2--){
            pOpnd1 *= a;
        }
        return pOpnd1;
        break;
    }
}
char orderBetween(char op1, char op2){
    return pri[optr2rank(op1)][optr2rank(op2)];
}
float evaluate(char* S){
    stack<float>opnd;
    stack<char>optr;
    optr.push('\n');
    while (!optr.empty()){
        if (isdigit(*S)){
            readNumber(S, opnd);
        }
        else{
            switch (orderBetween(optr.top(), *S)){
            case '<':
                optr.push(*S);
                S++;
                break;
            case '=':
                optr.pop();
                S++;
                break;
            case '>':{
                         char op = optr.top();
                         optr.pop();
                         if (op == '!'){
                             float pOpnd = opnd.top();
                             opnd.pop();
                             opnd.push(calcu(pOpnd));
                         }
                         else{
                             float pOpnd2 = opnd.top();
                             opnd.pop();
                             float pOpnd1 = opnd.top();
                             opnd.pop();
                             opnd.push(calcu(pOpnd1, op, pOpnd2));
                         }
                         break;
            }
            default:exit(-1);
            }
        }
    }
    float x = opnd.top();
    opnd.pop();
    return x;
}
int main(){
    char s[200],s1[250];
    int i = 0,k=0;
    while ((s[i++] = getchar()) != '\n');
    for (int j = 0; j < i; j++){
        if (s[j] != '-')s1[k++] = s[j];
        else{
            if (j == 0){
                s1[k++] = '(';
                s1[k++] = '0';
                s1[k++] = s[j];
                while (isdigit(s[++j]) && j<i)s1[k++] = s[j];
                s1[k++] = ')';
            }
           if (!isdigit(s[j - 1])){
                s1[k++] = '(';
                s1[k++] = '0';
                s1[k++] = s[j];
                while (isdigit(s[++j]) && j<i)s1[k++] = s[j];
                s1[k++] = ')';
                if(j<i)s1[k++] = s[j];
            }
            else s1[k++] = s[j];
        }
    }
    cout << evaluate(s1)<<endl; 
    return 0;
}
  • AC的代码,有待进一步深究:
#include<iostream>
#include<string>
#include<sstream>
#include<deque>
using namespace std;

void addNum(deque<string>&Q, int num){
    if (!Q.empty()){
        int cur = 0;
        if (Q.back() == "*" || Q.back() == "/"){
            string top = Q.back();
            Q.pop_back();
            stringstream ss(Q.back());
            ss >> cur;
            Q.pop_back();
            num = top == "*" ? (cur*num) : (cur / num);
        }
    }
    stringstream ss;
    ss << num;
    Q.push_back(ss.str());
}

int getNum(deque<string>& Q){
    int num = 0, R = 0;
    string f("+");
    while (!Q.empty()){
        stringstream ss(Q.front());
        ss >> num;
        Q.pop_front();
        R = (f == "+") ? (R + num) : (R - num);
        if (!Q.empty()){
            f = Q.front();
            Q.pop_front();
        }
    }
    return R;
}

int* value(string& s, int i){
    deque<string>Q;
    int pre=0;
    while (i < s.length() && s[i] != ')' && s[i] != ']' && s[i] != '}'){
        if (s[i] >= '0' && s[i] <= '9'){
            pre = pre * 10 + s[i++] - '0';
        }
        else if (s[i] != '(' && s[i] != '[' && s[i] != '{'){
            addNum(Q, pre);
            string ss;
            ss += s[i++];
            Q.push_back(ss);
            pre = 0;
        }
        else{
            int* bra = NULL;
            bra = value(s, i + 1);
            pre = bra[0];
            i = bra[1] + 1;
        }
    }
    addNum(Q, pre);
    int* R = new int[2];
    R[0] = getNum(Q);
    R[1] = i;
    return R;

}
int main(){
    string s;
    while (cin >> s){
        int *R = value(s, 0);
        cout << R[0] << endl;
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值