题目
大体意思就是,你是一个工作人员,你工作中老是遇到各种进制的表达式计算,你觉得太麻烦了,就想着 写一个多进制的计算器,给定进制和对应的表达式字符串,给出表达式计算的值。
思路
这个题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
更多推荐
华为笔试 多进制的计算器
发布评论