题解 | #表达式求值#

表达式求值

http://www.nowcoder.com/practice/9566499a2e1546c0a257e885dfdbf30d

#include<stdio.h>
#include<stdbool.h>
//将‘-’‘1‘‘0’变成-10
int chartonum(char* str, int i, int j) {
    bool neg = false;
    if (str[i] == '-') {
        neg = true;
        i++;
    }
    int res = str[i] - '0';
    while (++i <= j) {
        res = res * 10 + str[i] - '0';
    }
    return neg ? -1 * res : res;
}
//计算一个最简表达式如100*-500,-3,(-100)
int solveone(char* str, int i, int j) { 
    if (str[i] == '(' && str[j] == ')') return chartonum(str, i + 1, j - 1);
    int k = i + 1;
    while (k<j&&str[k] != '+' && str[k] != '-' && str[k] != '*' && str[k] != '/')k++;
    if (k == j)return chartonum(str, i, j);//-3
    int L = chartonum(str, i, k - 1), R = chartonum(str, k + 1, j);
    return str[k] == '+' ? L + R : str[k] == '-' ? L - R : str[k] == '*' ? L * R : L / R;
}
void cal(char* str, int i, int j) {//计算字符串i到j的部分,并将结果填回字符串
    int res = solveone(str, i, j);
    bool neg=false,sig=false;//neg该数是否为负,sig是否要添加‘+’或‘-’
    if (res <= 0) {
        res = -1 * res;
        neg = true;
        sig = true;
    }
    else 
        if (i > 0 && str[i - 1] != '(' && str[i - 1] >= '0' && str[i - 1] <= '9')sig = true;
    int len = 1,res1=res;
    while (res1 /= 10)len++;
    len += sig;//考虑符号占一位
    char t[32];//备份原字符串j后内容
    int k = 0;
    while (str[j + k+1]) {
        t[k] = str[j + k+1];
        k++;
    }
    t[k] = 0;
    int len1 = len;
    while (len1>1) {//最前面一个字符可能是符号,留一手
        str[i+len1-1] = res % 10+'0';
        res /= 10;
        len1--;
    }
    str[i] = sig ? neg? '-' :'+': res + '0';
    while (k >= 0) {
        str[i + len + k] = t[k];
        k--;
    }
}
void calop(char* str, int op) {//以运算符op为中心,计算一个单目表达式
    int i = op - 1, j = op + 2;
    while (str[j]&&str[j] >= '0' && str[j] <= '9')j++;
    j--;
    while (i>=0&& str[i] >= '0' && str[i] <= '9')i--;
    if (i<0||str[i] != '-')i++;
    cal(str, i, j);
}
bool calbra(char* str, int i, int j) {//计算一次左右括号分别在i和j的部分,更新字符串,返回是否消除此括号
    int plus = i, mul = i;//寻找两类运算符
    for (int k = j-1; k >=i+2; k--)
        if (str[k] == '+' || str[k] == '-')
            plus = k;
        else if (str[k] == '*' || str[k] == '/')
            mul = k;
    if (mul - i)
        calop(str, mul);
    else if (plus - i)
        calop(str, plus);
    else {
        if(i!=-1)cal(str, i, j);
        return true;
    }
    return false;
}
int main() {
    char str[101]="4+(6*(4*7-9*(0-8-4)*2))";
    while (~scanf("%s", str)) {
        int i=-1,j;
        while (1) {
            j = 0;
            while (str[j] && str[j] != ')')j++;
            if (str[j] == 0)break;
            for (i = j; i >= 0 && str[i] != '('; i--);
            calbra(str, i, j);
        }
        do {
            j = 0;
            while (str[j])j++;
        } while (!calbra(str, -1, j));
        if (str[0] == '-' && str[1] == '0' && str[2] == 0)
            printf("0\n");
        else
            printf("%s\n", str);
    }
}
全部评论

相关推荐

秋招进行到现在终于能写总结了。完全没想到战线会拉这么长,过程会如此狼狈,不过更应该怪自己太菜了。好在所有的运气都用在了最后,也是有个去处。背景:双2本硕科班,无竞赛,本科一段研究所实习,硕士一段大厂暑期实习但无转正。技术栈是C++&nbsp;&amp;&nbsp;Golang,实习是客户端音视频(而且是鸿蒙端开发),简历两个C++项目一个Golang项目。主要投递岗位:后端,cpp软开,游戏服务端,测开,以及一些不拘泥于Java的岗位。从8月起总共投递123家公司,笔试数不清了,约面大约30家。offer/oc/意向:友塔游戏(第一个offer,面试体验很好,就是给钱好少南瑞继保(计算机科班点击就送(限男生),不...
乡土丁真真:佬很厉害,羡慕~虽然我还没有到校招的时候,也想讲一下自己的看法:我觉得不是CPP的问题,佬的背书双2,技术栈加了GO,有两段实习。投了123,面了30.拿到11个offer。这个数据已经很耀眼了。这不也是CPP带来的吗?当然也不止是CPP。至少来说在这个方向努力过的也会有好的结果和选择。同等学历和项目选java就会有更好的吗?我个人持疑问态度。当然CPP在方向选择上确实让人头大,但是我觉得能上岸,至于最后做什么方向,在我看来并不重要。至于CPP特殊,有岗位方向的随机性,java不是不挑方向,只是没得选而已。也希望自己以后校招的时候能offer满满
点赞 评论 收藏
分享
totoroyyw:千年老妖😂
投递华为等公司10个岗位
点赞 评论 收藏
分享
10-15 09:13
已编辑
天津大学 soc前端设计
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务