问题描述
模拟程序型计算器,依次输入指令,可能包含的指令有
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
审题很重要,首次输入的值都是十进制,如果中间进行了进制转换,那么用到的值都要转换,所以不管是什么进制,都可以转换为十进制,最后输出的时候,再转换回去。还遇到一个pow()这个函数的坑,提交了之后一直是只有20分,还是慎用pow()函数,自己写一个速度更快,更好用(大神告诉我的)
#include<iostream>
#include<cmath>
#include<cstring>
using namespace std;
long long p_pow(long long k, long long n) //自己写的pow
{
long long res = 1;
for(int i = 0; i < n; i++)
{
res *= k;
}
return res;
}
long long changeToTen(string str, int k) //传过来数字字符串和现有的进制
{
long long res = 0;
long long x;
for(int i = str.length()-1; i >= 0; i--)
{
if(str[i] >= 'A' && str[i] <= 'Z')
{
x = str[i] - 'A' + 10;
}
else
{
x = str[i] - '0';
}
res += x * p_pow(k, str.length()-1-i);
}
return res;
}
string changeToOther(long long res, int k) //十进制转其他进制
{
if(res == 0)return "0";
string str;
while(res != 0)
{
int x = res % k;
if(x >= 10)
{
str.push_back('A' + x - 10);
}
else
{
str.push_back('0' + x);
}
res /= k;
}
string nstr;
for(int j = str.length()-1; j >= 0; j--)
nstr.push_back(str[j]);
return nstr;
}
long long YunSuan(long long number1, long long number2, int flag)
{
if(flag == 1)
return (number1 + number2);
else if(flag == 2)
return (number1 - number2);
else if(flag == 3)
return (number1 * number2);
else if(flag == 4)
return (number1 / number2);
else if(flag == 5)
return (number1 % number2);
}
int main()
{
long long n, number1, number2;
int k = 10;//起始进制为10
int flag = 0;//标明加1 减2 乘3 除4 模5 运算
cin>>n;
string inst1; //接收输入的首个指令
string inst2; //接收输入的数字字符串
int flag1 = 1;//判断输入的数字1还是数字2(最多俩数字相运算)
for(int i = 0; i < n; i++)
{
cin>>inst1;
if(inst1 == "CLEAR")
{
flag1 = 1; //出现CLEAR说明要输入第一个数字
}
else if(inst1 == "NUM")
{
cin>>inst2;
if(flag1 == 1){ //说明还未输入第一个数
number1 = changeToTen(inst2,k); //将输入的数字都转换为十进制
flag1 = 0; //第一个数输入结束
}
else //flag1不为1说明已经输入了第一个数,那么现在要输入的就是第二个数
{
number2 = changeToTen(inst2, k); //将输入的数字都转换为十进制
if(flag != 0)//说明有运算
{
number1 = YunSuan(number1, number2, flag);//进行运算
flag = 0; //运算结束,flag变为0
}
}
}
else if(inst1 == "CHANGE")
{
scanf("%d",&k);//进制转换为题目要求的进制
}
else if(inst1 == "EQUAL")
{
//将输出的数字都转换为相应的进制
cout<<changeToOther(number1, k)<<endl;
}
else if(inst1 == "ADD")
{
flag = 1;
}
else if(inst1 == "SUB")
{
flag = 2;
}
else if(inst1 == "MUL")
{
flag = 3;
}
else if(inst1 == "DIV")
{
flag = 4;
}
else if(inst1 == "MOD")
{
flag = 5;
}
}
return 0;
}