欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

蓝桥杯往届题目——小计算器(c语言实现)

程序员文章站 2022-06-08 22:21:28
...

问题描述

模拟程序型计算器,依次输入指令,可能包含的指令有
  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’表示1035

输入格式

第1行:1个n,表示指令数量
  第2…n+1行:每行给出一条指令。指令序列一定以’CLEAR’作为开始,并且满足指令规则

输出格式

依次给出每一次’EQUAL’得到的结果

样例输入

7
CLEAR
NUM 1024
CHANGE 2
ADD
NUM 100000
CHANGE 8
EQUAL

样例输出

2040

思路:利用堆栈的思想,本题利用数组实现
代码如下:

#include<stdio.h>
#include<string.h>
unsigned long long opt[10000001];//操作数 
unsigned long long changeToTen(int x,char *num)//代表的进制,先都转为10进制 
{
	int i;
	unsigned long long res=0;
	for(i=0;i<strlen(num);i++)
	{
		if(num[i]-'0'<=9)
			res = x*res+num[i]-'0';
		else 
			res = x*res+num[i]-55;
	}
	return res;
}
void change(unsigned long long num,int radix)//使用除n取余数法 
{
	int count=0,i;
	unsigned long long mid;
	unsigned long long pos[1001];
	if(!num)
	{
		printf("0\n");
		return;
	 } 
	while(num!=0)
	{
		mid=num%radix;
		pos[count++]=mid;//将余数保存 
		num/=radix;
	}
	for(i =count-1;i>=1;i--)
	{
		if(pos[i]<10)
			printf("%lld",pos[i]);
		else
			printf("%c",pos[i]+55);
	}
		if(pos[0]<10)
			printf("%lld\n",pos[0]);
		else
			printf("%c\n",pos[0]+55);
}
void chooseMethod(int *flag,int *len)
{
	unsigned long long res;
	//printf("%d %d\n",*flag,*len);
	if(*flag==1)//加法,注意是(*len)--,不是*len--,涉及优先级 
	{
		res = opt[(*len)-2]+opt[(*len)-1];
		opt[(*len)-2]=res;
		(*len)--;
		//printf("加法结果为:%lld %d\n",res,*len);
	}
	else if(*flag==2)//减法 
	{
		res = opt[(*len)-2]-opt[(*len)-1];
		opt[(*len)-2]=res;
		(*len)--;
		//printf("减法结果为:%lld\n",opt[(*len)-1]);
	}
	else if(*flag==3)//乘法 
	{
		res = opt[(*len)-2]*opt[(*len)-1];
		opt[(*len)-2]=res;
		(*len)--;
		//printf("乘法结果为:%lld\n",opt[(*len)-1]);
	}
	else if(*flag==4)//除法 
	{
		res = opt[(*len)-2]/opt[(*len)-1];
		opt[(*len)-2]=res;
		(*len)--;
		//printf("除法结果为:%lld\n",opt[(*len)-1]);
	}
	else if(*flag==5)//取余 
	{
		res = opt[(*len)-2]%opt[(*len)-1];
		opt[(*len)-2]=res;
		(*len)--;
		//printf("取余结果为:%lld\n",opt[(*len)-1]);
	}
	*flag=0;
}
int main()
{
	int n,i,flag=0;//flag为0说明什么操作都没有 
	int jinzhi=10;//最终的进制 
	int count = 0;
	unsigned long long res;//res为计算数值 
	scanf("%d",&n);
	char order[1001];
	char num[10001];
	for(i=0;i<n;i++)
	{
		scanf("%s",order);
		if(strcmp(order,"NUM")==0)//其后跟一个数 
		{
			scanf("%s",num);
			opt[count++]=changeToTen(jinzhi,num);//转为十进制数
			//printf("数为:%lld\n",opt[count-1]);
			chooseMethod(&flag,&count);
		}
		else if(strcmp(order,"CLEAR")==0)
		{
			if(count>0)
				count--;
		}
		else if(strcmp(order,"ADD")==0)//加法运算 
		{
			flag=1;
		}
		else if(strcmp(order,"SUB")==0)//减法运算 
		{
			flag=2;
		}
		else if(strcmp(order,"MUL")==0)
		{
			flag=3;
		}
		else if(strcmp(order,"DIV")==0)
		{
			flag=4;
		}
		else if(strcmp(order,"MOD")==0)
		{
			flag=5;
		}
		else if(strcmp(order,"CHANGE")==0)
		{
			scanf("%d",&jinzhi);
		}
		else if(strcmp(order,"EQUAL")==0)
		{
			change(opt[count-1],jinzhi);//注意不一定每次都是在0 
		}
	}
	return 0;
}