蓝桥杯 小计算器 C++详细说明
程序员文章站
2022-06-08 22:13:48
...
问题描述
模拟程序型计算器,依次输入指令,可能包含的指令有
1. 数字:'NUM X',X为一个只包含大写字母和数字的字符串,表示一个当前进制的数
2. 运算指令:'ADD','SUB','MUL','DIV','MOD',分别表示加减乘,除法取商,除法取余
3. 进制转换指令:'CHANGE K',将当前进制转换为K进制(2≤K≤36)
4. 输出指令:'EQUAL',以当前进制输出结果
5. 重置指令:'CLEAR',清除当前数字
指令按照以下规则给出:
数字,运算指令不会连续给出,进制转换指令,输出指令,重置指令有可能连续给出
运算指令后出现的第一个数字,表示参与运算的数字。且在该运算指令和该数字中间不会出现运算指令和输出指令
重置指令后出现的第一个数字,表示基础值。且在重置指令和第一个数字中间不会出现运算指令和输出指令
进制转换指令可能出现在任何地方
运算过程中中间变量均为非负整数,且小于2^63。
以大写的'A'~'Z'表示10~35
输入格式
第1行:1个n,表示指令数量
第2..n+1行:每行给出一条指令。指令序列一定以'CLEAR'作为开始,并且满足指令规则
输出格式
依次给出每一次'EQUAL'得到的结果
样例输入
7
CLEAR
NUM 1024
CHANGE 2
ADD
NUM 100000
CHANGE 8
EQUAL
样例输出
2040
看到这题时的问题:
-
问题一:
可以转换的进制为(2 <= k <= 36),有没有人看到这个就奔溃了,我真得写这么多进制转换函数吗?不写的话怎么办?可以写一个进制转换模板函数吗?可以的话怎么写?解决:每当遇到复杂问题,我们都喜欢往简单像。所以,我们在运算时统一用10进制数算,等到输出的时候转换成相应进制就行。是不是就简单很多了。
int base = m; //base为进制数,m可以为2~36
举例:
int base = 10;
string s = "1024";
long long x = 0;
for(int i = 0;i < s.size();i++){
long long temp = isdigit(s[i]) ? s[i] - '0' : x = s[i] + 10 - 'A';
//最重要的是这个公式,这个公式能使其他进制数转换为10进制数
x = x * base + temp;//知道这个公式怎么推吗?欢迎留言评论^ ^
}
总结:
记住这个公式。这就是进制转换模板,这个函数的参数是什么,怎样和其他函数对接。
见下文的设计思想。
- 问题二: 怎样实现从10进制转换成其他进制
解决:
1、使用一个vector来存放的内容。
2、 % 其他进制数 (% 8等)放入vector中,如果余数大于10记得转换成相应的字母。
3、vector中的内容逆序输出才是对应的进制数
void print(){
vector<char> v;
long long x = sum;//所要转换的数,可能是做了运算后的数,也可能是clear后的第一个数。
while(x){
int cur = x % base;
if(cur >= 0 && cur <= 9){
//比如cur = 1 和 cur + '0' 读者自行执行printf("%d\n",cur);和printf("%c\n",cur+'0');有助于理解
v.push_back(cur+'0');
}else{
//为什么要减10呢?如果不减的话对应不上ASCLL码。就上面两个printf输出的结果不一样,10-35已经是36个数了,减了10后刚好够26个字母。
v.push_back(cur-10+'A');
}
x /= base;
}
//注意!!我们运算后sum = 0 或者是第一个数给的是0
if(v.size() == 0)
cout << "0" << endl;
for(int i = vector.size() - 1;i >= 0;i--){//有的地方判断条件可能是~i,意思就是说i=-1的时候退出。
因为-1的机器码(负数的机器码是 补码)是全1,~称为按位取反,取反就全0,就不执行for循环了。
cout << v[i];
}
cout << endl;
}
这两个问题都解决了就可以写main函数了
#include <bits/stdc++.h>
using namespace std;
int base = 10; //初始为10
long long sum = 0; //运算后的数
//输出相应进制数
void print(){
vector<char> v;
long long x = sum;
while(x){
int cur = x % base;
if(cur <= 9){
v.push_back(cur+'0');
}else{
v.push_back(cur-10+'A');
}
x /= base;
}
if(v.size() == 0){
cout << "0" << endl;
return;
}
for(int i = v.size() - 1;i >= 0;i--){
cout << v[i];
}
cout << endl;
}
//转换为10进制
long long get_decimal(){
string s;
cin >> s;
long long x = 0;
for(int i = 0;i < s.size();i++){
long long temp = isdigit(s[i]) ? s[i] - '0' : s[i] + 10 - 'A';
x = x * base + temp;
}
return x;
}
int main(){
int n; //指令数
cin >> n;
string op; //指令
int opi = 0; //指令下标
while(n--){
cin >> op;
if(op == "CLEAR") opi = sum = 0;
else if(op == "CHANGE") cin >> base;
else if(op == "EQUAL") print();
else if(op == "ADD") opi = 2;
else if(op == "SUB") opi = 3;
else if(op == "MUL") opi = 4;
else if(op == "DIV") opi = 5;
else if(op == "MOD") opi = 6;
else if(op == "NUM"){
switch(opi){
case 0: sum = get_decimal(); break;//CLEAR后的第一个数
case 2: sum += get_decimal();break;
case 3: sum -= get_decimal();break;
case 4: sum *= get_decimal();break;
case 5: sum /= get_decimal();break;
case 6: sum %= get_decimal();break;
}
}
}
return 0;
}
上一篇: docker容器跨服务器的迁移的方法
下一篇: 使用docker搭建gitlab详解