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

时间:2019-12-07
本文章向大家介绍蓝桥杯 十六进制转8进制【模拟】,主要包括蓝桥杯 十六进制转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)    // 第一位放置 字符,第二位放字符串结束符'\0'
                    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;
}

原文地址:https://www.cnblogs.com/expedition/p/12003115.html