[蓝桥杯_历届试题] 小计算器

小计算器

问题描述

  模拟程序型计算器,依次输入指令,可能包含的指令有


  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;
	
} 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值