蓝桥杯 小计算器(C++)

本文介绍了如何通过编程解决一个涉及进制转换、运算和指令识别的问题,详细解释了代码中关键部分的逻辑,包括字符和数字的转换、不同进制间的转换函数以及处理不同指令的操作。
摘要由CSDN通过智能技术生成

一、题目描述

二、解题思路

        感觉没啥好讲的 照着要求一点一点做就行了 还是直接贴代码吧

        这里主要说明一下代码的部分实现

       1. 考虑到最大到35进制 会出现字母 所以对每次计算的中间结果 ans 用字符串类型string表示

       2. 数可能很大 涉及到计算的操作 全用long long类型定义

       3. 关于指令 order 的输入和识别  因为order可能有空格 所以用getline()函数 当然还有另外一种思路,就是把NUM X分解为两条指令 依次读取,然后再根据运算符opt是否已经被赋值来进行对 ans 的更新  然后是识别  因为最多只要知道指令的前两个字母 就可以知道是什么指令了 然后在进行相应的操作

       4. 指令NUM X 作为一个字符串 要获取X 用 .substr(int i)方法即可 这里i = 4,这个方法可以有不止一个参数 

       5. 进制转换 CHANGE X 注意X可能是个两位数 分开判断一下

       6. 进制转换函数  十进制转到其他高进制  如果是0  考虑可能 result 会是 "" 开始就判断一下 如果是0直接输出"0" . 

       7. 运算函数 接收的数字 以及ans 都是字符串类型 先转换回十进制整型再计算  然后再以字符串形式返回相应的进制形式

       8.对于CLEAR指令 只是清楚当前的数  当前的进制并不改变 

       9. 当然方法不唯一  如果你觉得可以用其他的方式 尽情去尝试吧 只要能通过就OK

    三、代码 

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

//字符转数字
int c2i(char c){
    if(isdigit(c)) return c - '0';
    else return c - 'A' + 10;
}

//数字转字符
char i2c(int digit){
    if(digit < 10)  return digit + '0';
    else return digit - 10 + 'A';
}

//其它进制转十进制 [返回整型]
ll o2t(string  num,int k){
    ll mid = 0;
    ll pow = 1;

    for(int i = num.length() - 1;i >= 0;i--)
    {
        mid += c2i(num[i]) * pow;
        pow *= k;
    }
    return mid;
}

//十进制转其他进制
string t2o(ll num,int r)
{
    if(num == 0) return "0";
    string result ;
    while(num > 0){
        int remainder = num % r;
        result = i2c(remainder) + result;
        num /= r; 
    }
    return result;
}

//把一个k进制转为r进制
string change(string num,int k,int r)
{
    if(num == "0") return "0";
    
    //先转十进制作为中间结果
    ll mid = 0;
    ll pow = 1;

    for(int i = num.length() - 1;i >= 0;i--)
    {
        mid += c2i(num[i]) * pow;
        pow *= k;
    }

    //十进制转为r进制
    string result;
    while(mid > 0){
        int remainder = mid % r;
        result = i2c(remainder) + result;
        mid /= r; 
    }
    return result;
}
//运算函数
string calculate(string ans,string str1,char opt,int k){
    //两个操作数
    ll s1 = o2t(ans,k);
    ll s2 = o2t(str1,k);
    if(opt == '\0') return str1;
    else if(opt == '+') return t2o(s1 + s2,k);
    else if(opt == '-') return t2o(s1 - s2,k);
    else if(opt == '*') return t2o(s1 * s2,k);
    else if(opt == '/') return t2o(s1 / s2,k);
    else if(opt == '%') return t2o(s1 % s2,k);
}
int main()
{
    //k 表示当前进制  r表示要更改到的进制
    int k = 10, n, r;
    string ans;

    char opt = '\0'; 
    scanf("%d\n",&n);
    string order;
    while(n){
        getline(cin,order);
        //cout << order << endl; 
        //指令的识别?
        if(order[0] == 'A') opt = '+';
        else if(order[0] == 'S') opt = '-';
        else if(order[0] == 'M') {
            if(order[1] == 'U') 
            opt = '*';
            else 
            opt = '%';
        }
        else if(order[0] == 'D') opt = '/';
        
        else if(order[0] == 'C'){
            //清楚数据
            if(order[1] == 'L') opt = '\0',ans = "0";
            //进制转换
            else {
                if(order.length() == 8) r = order[7] - '0';   //2~9 进制
                else r = 10 * (order[7] - '0') + (order[8] - '0');  //10~35 进制
                ans = change(ans,k,r);
                //修改当前进制
                k = r;
            }
        }
        //有新的操作数
        else if(order[0] == 'N'){
            string num1 = order.substr(4);
            ans = calculate(ans,num1,opt,k);
        }
        else if(order[0] == 'E')
        cout << ans << endl;
        n--;
        //cout << ans << endl;
        //cout << n << endl; 
    }  
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值