noip信息学一本通1356:计算(calc)

时间限制: 1000 ms 内存限制: 65536 KB
提交数: 3892 通过数: 1465
【题目描述】
小明在你的帮助下,破密了Ferrari设的密码门,正要往前走,突然又出现了一个密码门,门上有一个算式,其中只有“(”,“)”,“0-9”,“+”,“-”,“*”,“/”,“^”,求出的值就是密码。小明数学学得不好,还需你帮他的忙。(“/”用整数除法)

【输入】
共1行,为一个算式。

【输出】
共1行,就是密码。

【输入样例】
1+(3+2)(7^2+69)/(2)
【输出样例】
258
【来源】

No

#include
#include
#include
#include
#include

using namespace std;

int number[101],i=0, p=1;
char symbol[101],s[256],t[256];

void push() { //算符入栈运算
    symbol[++p]=s[i];
}

void pop() { //运算符栈顶元素出栈,并取出操作数栈元素完成相应的运算
    switch (symbol[p--]) { //运算完成之后扔掉运算符,也标志着需要运算的数已经运算完成
        case '+': {
            number[p]+=number[p + 1];
            break;
        }
        case '-': {
            number[p]-=number[p + 1];
            break;
        }
        case '*': {
            number[p]*=number[p + 1];
            break;
        }
        case '/': {
            number[p]/=number[p + 1];
            break;
        }
        case '^': {
            number[p]=pow(number[p],number[p + 1]);
        }
    }
}

bool can() { //判断运算符的优先级别,建立标志函数,能否进行运算
    if ((s[i]=='+'||s[i]=='-')&&symbol[p]!='(')//如果不是‘(’,则需要出栈,因为+与-的运算优先级别较低,仅仅比‘(’大
        return 1;
    if ((s[i]=='*'||s[i]=='/')&&(symbol[p]=='*'||symbol[p]=='/'))
//若遇到乘除且运算符数组中对应的恰好是乘除,则需要出栈
        return 1;
    return 0;
}

bool judge(char s[256]) {
    int top=0,i=0;
    while (s[i]!='@') {
        if (s[i]=='(')top++;
        if (s[i]==')') {
            if (top>0) top--;
            else return 0;
        }
        i++;
    }
    if (top!=0) return 0; //检测栈是否为空。不空则说明有未匹配的括号
    else return 1;
}

int main() {
    gets(s);
    if(judge(s)==0) {
        cout<<"NO";
        return 0;
    }

    s[strlen(s)]=')';
    symbol[p]='(';
    while (i<strlen(s)) {
        while (s[i]=='(') { //左括号处理,压入左括号,有了左括号才能进行与右括号的匹配 while (symbol[p]!=‘(‘)
            push();
            i++;
        }
        int x=0;
        while (s[i]>='0'&&s[i]<='9') //取数入操作数栈
            x=x*10+s[i++]-'0';
        number[p]=x;
        do {
            if (s[i]==')') { //当右括号后面还有右括号时处理
                while (symbol[p]!=')')
                    pop();//当括号内还有算式没有算完时进行运算
                number[--p]=number[p + 1];//当运算完成以后左括号已经没有意义,所以将指针p移向前一个运算符,并复制所得的结果
            } else {
//根据标志函数值作运算符入栈或出栈运算处理
                while (can())
                    pop();// 当可以进行运算时运算,然后压入一个运算符
                push();
            }
            i++;
        } while (i<strlen(s)&&s[i-1]==')');//当检测到右括号时,可以运算括号内的内容
    }
    printf("Result=%d", number[0]);//这个是建立在最后有‘@’的情况下。因为所有的运算全部是建立在括号之内的,所以随着运算符的减少(运算符减少同时标志着需要操作的数减少)和最后的p--,结果一定保存在number[0]内
//printf("Result=%d",number[1]);
//如果需要不输入‘@’的运算式,则只需把从number【0】输出改为number【1】就好啦~
    return 0;
}

你可能感兴趣的:(NOIP信息学)