📜  C |运营商|问题18(1)

📅  最后修改于: 2023-12-03 14:39:41.143000             🧑  作者: Mango

C运营商问题18

简介

C运营商问题18是一道经典的编程算法题,它在程序员技术面试中经常被提出。该问题的主要目标是计算给定的算术表达式在运算符优先级规则下的结果。该问题的解决方案既可以使用栈,也可以使用递归。该问题具有一定的难度,需要借助于对算术运算符的运算优先级了解和对栈数据结构的掌握。

问题描述

给定一个只包含加减乘除四种运算符和整数的算术表达式,例如:3+5*6-8/2。请编写一个算法来计算该表达式在运算符优先级规则下的结果。

解题思路

该问题的解决需要首先对算术表达式进行词法分析,将表达式中的数字、运算符等符号以某种格式进行识别,例如存储为一个个token。然后对于优先级最高的乘除,我们需要先将其运算出结果,并将中间结果存储回token序列中,以便后续的运算符使用。最后再按顺序运算加减法即可。

代码实现
#include <stdio.h>
#include <ctype.h>

double stod(char *s) {
    int integer = 0, decimal = 0, sign = 1, stage = 1;
    if (*s == '-') {
        sign = -1;
        s++;
    }
    while (isdigit(*s) || *s == '.') {
        if (*s == '.') {
            stage = 0.1;
            s++;
            continue;
        }
        if (stage == 1) {
            integer = integer * 10 + (*s - '0');
        } else {
            decimal = decimal + (*s - '0') * stage;
            stage *= 0.1;
        }
        s++;
    }
    return sign * (integer + decimal);
}

int priority(char c) {
    switch(c) {
        case '+':
        case '-':
            return 1;
        case '*':
        case '/':
            return 2;
        default:
            return 0;
    }
}

double eval(char* *s) {
    double l = 0, r = 0, res = 0;
    char op = 0;
    while (isspace(**s)) {
        (*s)++;
    }
    if (**s == '(') {
        (*s)++;
        l = eval(s);
        while (isspace(**s)) {
            (*s)++;
        }
        op = **s;
        (*s)++;
        r = eval(s);
        while (isspace(**s)) {
            (*s)++;
        }
        (*s)++;
        if (op == '+') {
            return l + r;
        } else if (op == '-') {
            return l - r;
        } else if (op == '*') {
            return l * r;
        } else {
            return l / r;
        }
    } else {
        return stod(*s);
    }
}

double calculate(char *s) {
    double ans = 0;
    char *tokens = (char*)calloc(strlen(s), sizeof(char));
    int idx = 0;
    for (int i = 0; i < strlen(s); i++) {
        if (isdigit(s[i])) {
            int j = i;
            while (j < strlen(s) && isdigit(s[j])) {
                tokens[idx++] = s[j++];
            }
            i = j - 1;
        } else if (s[i] == '(' || s[i] == '+' || s[i] == '-' || s[i] == '*' || s[i] == '/') {
            tokens[idx++] = s[i];
        }
    }
    int cur = -1;
    char *stack = (char*)calloc(strlen(tokens), sizeof(char));
    for (int i = 0; i < strlen(tokens); i++) {
        if (tokens[i] == '(') {
            stack[++cur] = tokens[i];
        } else if (tokens[i] == '+' || tokens[i] == '-' || tokens[i] == '*' || tokens[i] == '/') {
            while (cur >= 0 && priority(stack[cur]) >= priority(tokens[i])) {
                char op = stack[cur--];
                if (op == '+') {
                    ans = eval(&stack) + ans;
                } else if (op == '-') {
                    ans = ans - eval(&stack);
                } else if (op == '*') {
                    ans = eval(&stack) * ans;
                } else {
                    ans = ans / eval(&stack);
                }
            }
            stack[++cur] = tokens[i];
        } else if (tokens[i] == ')') {
            while (cur >= 0 && stack[cur] != '(') {
                char op = stack[cur--];
                if (op == '+') {
                    ans = eval(&stack) + ans;
                } else if (op == '-') {
                    ans = ans - eval(&stack);
                } else if (op == '*') {
                    ans = eval(&stack) * ans;
                } else {
                    ans = ans / eval(&stack);
                }
            }
        } else {
            ans += stod(&tokens[i]);
        }
    }
    while (cur >= 0) {
        char op = stack[cur--];
        if (op == '+') {
            ans = eval(&stack) + ans;
        } else if (op == '-') {
            ans = ans - eval(&stack);
        } else if (op == '*') {
            ans = eval(&stack) * ans;
        } else {
            ans = ans / eval(&stack);
        }
    }
    return ans;
}
总结

C运营商问题18是一个比较经典的编程题目,在学习编程的过程中非常有意义。本文中我们介绍了该问题的具体描述,解题思路以及代码实现。在实现过程中,我们使用了栈数据结构和递归算法,需要深入了解算术运算符的优先级规则才能更好地完成该问题的解答。