题目

          大体意思就是,你是一个工作人员,你工作中老是遇到各种进制的表达式计算,你觉得太麻烦了,就想着 写一个多进制的计算器,给定进制和对应的表达式字符串,给出表达式计算的值。

思路

          这个题300分,但是我觉得不算难,因为之前做过一个十进制的计算器设计的力扣题,十进制的我会了,其他进制的,我不想麻烦了,那就先把表达式都转成十进制的呗,然后调十进制的计算函数。最后得到的结果再转成对应进制

各模块代码

先导入一些库文件

#include <bitset>
#include <iostream>
#include <stack>
#include <string>
using namespace std;

          写一个其他进制转十进制表达式的,思路很简单遇到 +、-、*、/、(、) 这种运算符就保持原样,数字就把他转成10进制(c的库函数strtol),如何获得数字对应的字符串也简单,不断往后遍历,指导遇到一个运算符

string help(string s, int base) {
    int n = s.size();
    int i = 0;
    string res = "";
    char* stop;
    while (i < n) {
        if (s[i] != '+' && s[i] != '-' && s[i] != '*' && s[i] != '/' && s[i] != '(' && s[i] != ')') {
            string temp = "";  //数字字符串
            while (i < n && (s[i] != '+' && s[i] != '-' && s[i] != '*' && s[i] != '/' && s[i] != '(' && s[i] != ')')) {  //不是运算符那就是数字的一部分
                temp += s[i];
                i++;
            }
            const char* st = temp.c_str();   //由于strtol只接受char *参数,做个转换
            long ans = strtol(st, &stop, base);  // 数字字符串转成十进制长整型
            res += to_string(ans);
            continue;
        } else {  // s[i] 是运算符就直接加
            res += s[i];  
            i++;
        }
    }
    return res;
}

          再写一个把最后的结果转成对应进制的函数,,其实就是十进制转任意进制了

string ten_to_r(int n, int r)  //将10进制的n转为r进制  23 2
{
    char s[105] = {0};
    int k = 0;
    stack<int> str;
    while (n != 0) {
        str.push(n % r);  //将余数存在栈中
        n = n / r;
    }
    int m = 0;
    while (!str.empty())  //倒序输出余数即为转换后的答案
    {
        int t = str.top();
        if (t >= 10)
            s[m++] = t - 10 + 'A';  //大于10时数字转字符 如10 -> A
        else
            s[m++] = t + '0';  //数字转字符
        str.pop();
    }
    return s;
}

          然后来一个十进制计算器的设计,就完事儿

int calculate(string s) {
    char op = '+';
    int num = 0;
    int result = 0;
    stack<int> x;
    int i = 0;
    while (i < s.size()) {
        if (s[i] >= '0' && s[i] <= '9') {
            num *= 10;
            num += s[i] - '0';
        } else if (s[i] == '(') {
            int count = 0;
            int j = i;
            for (; i < s.size(); i++) {
                if (s[i] == '(')
                    count++;
                if (s[i] == ')')
                    count--;
                if (count == 0)
                    break;
            }
            num = calculate(s.substr(j + 1, i - j - 1));
        }
        if (s[i] == '+' || s[i] == '-' || s[i] == '*' || s[i] == '/' || i == s.size() - 1) {
            if (op == '+')
                x.push(num);
            else if (op == '-')
                x.push(-num);
            else if (op == '*') {
                int temp = x.top() * num;
                x.pop();
                x.push(temp);
            } else if (op == '/') {
                int temp = x.top() / num;
                x.pop();
                x.push(temp);
            }
            op = s[i];
            num = 0;
        }
        i++;
    }

    while (!x.empty()) {
        result += x.top();
        x.pop();
    }
    return result;
}

完整代码与测试

#include <bitset>
#include <iostream>
#include <stack>
#include <string>
using namespace std;

string ten_to_r(int n, int r)  //将10进制的n转为r进制  23 2
{
    char s[105] = {0};
    int k = 0;
    stack<int> str;
    while (n != 0) {
        str.push(n % r);  //将余数存在栈中
        n = n / r;
    }
    int m = 0;
    while (!str.empty())  //倒序输出余数即为转换后的答案
    {
        int t = str.top();
        if (t >= 10)
            s[m++] = t - 10 + 'A';  //大于10时数字转字符 如10 -> A
        else
            s[m++] = t + '0';  //数字转字符
        str.pop();
    }
    return s;
}

string help(string s, int base) {
    int n = s.size();
    int i = 0;
    string res = "";
    char* stop;
    while (i < n) {
        if (s[i] != '+' && s[i] != '-' && s[i] != '*' && s[i] != '/' && s[i] != '(' && s[i] != ')') {
            string temp = "";
            while (i < n && (s[i] != '+' && s[i] != '-' && s[i] != '*' && s[i] != '/' && s[i] != '(' && s[i] != ')')) {  //不是运算符那就是数字的一部分
                temp += s[i];
                i++;
            }
            const char* st = temp.c_str();
            long ans = strtol(st, &stop, base);
            res += to_string(ans);
            continue;
        } else {
            res += s[i];
            i++;
        }
    }
    return res;
}

int calculate(string s) {
    char op = '+';
    int num = 0;
    int result = 0;
    stack<int> x;
    int i = 0;
    while (i < s.size()) {
        if (s[i] >= '0' && s[i] <= '9') {
            num *= 10;
            num += s[i] - '0';
        } else if (s[i] == '(') {
            int count = 0;
            int j = i;
            for (; i < s.size(); i++) {
                if (s[i] == '(')
                    count++;
                if (s[i] == ')')
                    count--;
                if (count == 0)
                    break;
            }
            num = calculate(s.substr(j + 1, i - j - 1));
        }
        if (s[i] == '+' || s[i] == '-' || s[i] == '*' || s[i] == '/' || i == s.size() - 1) {
            if (op == '+')
                x.push(num);
            else if (op == '-')
                x.push(-num);
            else if (op == '*') {
                int temp = x.top() * num;
                x.pop();
                x.push(temp);
            } else if (op == '/') {
                int temp = x.top() / num;
                x.pop();
                x.push(temp);
            }
            op = s[i];
            num = 0;
        }
        i++;
    }

    while (!x.empty()) {
        result += x.top();
        x.pop();
    }
    return result;
}

int main() {
    string s = "(1-2)*3+4";
    int base = 10;
    string temp = help(s, base);
    int res = calculate(temp);
    cout << ten_to_r(res, base) << endl;
    
    s = "101+11";
    base = 2;
    temp = help(s, base);
    res = calculate(temp);
    cout << ten_to_r(res, base) << endl;
    
    s = "af00+ff";
    base = 16;
    temp = help(s, base);
    res = calculate(temp);
    cout << ten_to_r(res, base) << endl;

    return 0;
}

输出

1
1000
AFFF

更多推荐

华为笔试 多进制的计算器