• 蓝桥杯 十六进制转8进制【模拟】


    问题描述
      给定n个十六进制正整数,输出它们对应的八进制数。

    输入格式
      输入的第一行为一个正整数n (1<=n<=10)。
      接下来n行,每行一个由0~9、大写字母A~F组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。

    输出格式
      输出n行,每行为输入对应的八进制正整数。

      【注意
      输入的十六进制数不会有前导0,比如012A。
      输出的八进制数也不能有前导0。

    样例输入
      2
      39
      123ABC

    样例输出
      71
      4435274

    #include<stdio.h>
    #include<string>
    #include<iostream>
    #include<string.h>
    using namespace std;
    
    
    char a[16][5] = {"0000","0001","0010","0011","0100","0101","0110","0111","1000","1001","1010","1011","1100","1101","1110","1111"};
    int main(){
      
        int n;
        char x[100000];
        scanf("%d",&n);
        while(n--){
            scanf("%s",x);
            string y;
            int lon = strlen(x);
            for(int i = 0; i < lon;i++){
                int num;
                // 根据16进制字符串 从前往后 构建拼接 二进制字符串
                
                if(x[i] >= 65 && x[i] <= 70){ //如果是 十六进制ABCDEF
                    num = x[i] - 55;
                    y.append(a[num]);
                }else{//十六进制的数字
                    num = x[i] -48;
                    y.append(a[num]);
                }
            }
            int mk;
            int lon2 = y.size();
            if(y[0] == '0'){ //如果该二进制字符串首字符是'0'
                for(int i = 1; i < lon2;i++)
                    if(y[i] != '0'){
                        mk = i;
                        break;
                    }//二进制字符串首部有几位连续的'0'
                
                //按照'0'的位数向前移动字符串
                for(int i = 0; i < lon2-mk;i++)
                    y[i] = y[i+mk];
                //将字符串最后由于移动而无效的位置删除
                y.erase(lon2-mk,mk);
            }
            //由于字符串可能向前移动,所以一定要重新获取字符串的长度
            lon2 = y.size();
            int j = 0;
            int all = 0;
            int cc = 1;
            string resu;//最后的8进制串
            //从二进制变为八进制,是将二进制字符串从后往前
            //每3位一组【不满3位的,前面补字符'0'】,转换成对应的十进制字符,拼接构造
            //为了简化补字符'0'的操作,直接将二进制字符串从后往前,每3位一组,每组按照百位、十位、个位求和
            //不够3位的,由于补的是'0',所以直接无视这个操作,求和就行
            char kk[2];
            for(int i = lon2-1;i >= 0;i--){
                int num = y[i]-48; //将字符'1' '0'变为 1  0,方便求和
                all += num*cc;
                cc = cc * 10;//不断变化的百、十、个位
                j++;
                if(j == 3 || i == 0){ // j == 3 是满足了 “三个一组”    
                    if(all == 1)      // i == 0是满足了“到达二进制串的末尾,无视不够3位一组的情况下补'0'操作”
                        kk[0] = '1';
                    if(all == 10)
                        kk[0] = '2';
                    if(all == 11)
                        kk[0] = '3';
                    if(all == 100)
                        kk[0] = '4';
                    if(all == 101)
                        kk[0] = '5';
                    if(all == 110)
                        kk[0] = '6';  //char kk[2]的目的是,append()操作只针对字符串,所以一个长度为2的字符串数组搞定
                    if(all == 111)    // 第一位放置 字符,第二位放字符串结束符''
                        kk[0] = '7';
                    if(all == 0)
                        kk[0] = '0';//根据求和的数字,匹配对应的8进制字符
                    resu.append(kk);//拼接构建   
                    all = 0;
                    cc = 1;
                    j = 0;
                }
            }
            int lon3 = resu.size();
            for(int i = lon3 - 1;i >= 0;i--)//反向输出,,因为二进制串是从后往前扫描,而append()是加到后面的
                printf("%c",resu[i]);
            cout<<endl;
        }
        return 0;
    }
  • 相关阅读:
    Java多线程系列 基础篇10 wait/notify/sleep/yield/join
    Java多线程系列 基础篇09 Object.wait/notifyJVM源码实现
    Java多线程系列 基础篇07 synchronized底层优化
    Java多线程系列 基础篇06 synchronized(同步锁)
    Java多线程系列 基础篇05 synchronized关键字
    Java多线程系列 基础篇04 线程中断
    Java多线程系列 基础篇03 线程的优先级和守护线程
    Java多线程系列 基础篇02 线程的创建和运行
    MySQL进阶14--标识列(自增序列/auto_increment)--设置/展示步长--设置/删除标示列
    MySQL进阶13--常见六大约束: 非空/默认/主键/唯一约束/检查约束/外键约束--表级约束 / 列级约束
  • 原文地址:https://www.cnblogs.com/expedition/p/12003115.html
Copyright © 2020-2023  润新知