蓝桥杯-十六进制转八进制

本程序处理的情况是当十六进制数很大的时候,比如有100000位。
程序由算法和数据结构组成:
1、算法:将16进制转换成2进制,再转换成8进制。
2、数据结构:16进制转换成2进制不用反复除,取余,而是将每位16进制位数hash成4位二进制数,保存在数组Hash1和Hash2中。2进制转换成8进制也同样将每三位2进制hash成一位八进制数保存在数组Hash3中。这样大大节省了时间!
注意:如何消除前导0。

#include <stdio.h>
#include <fstream>
#include <string.h>
#include<iostream>
#include<algorithm>
int n;
int Hash1[7][5]={{1,0,1,0},{1,0,1,1},{1,1,0,0},{1,1,0,1},{1,1,1,0},{1,1,1,1} 
                };//十六进制的'A'---'E'转二进制
int Hash2[11][5]={{0,0,0,0},{0,0,0,1},{0,0,1,0},{0,0,1,1},{0,1,0,0},
                {0,1,0,1},{0,1,1,0},{0,1,1,1},{1,0,0,0},{1,0,0,1}
                };//十六进制的'0'---'9'转二进制
int Hash3[3][3][3];//二进制转八进制 
char arr[100005];//输入十六进制 
int tmp[400005];//保存二进制;
int ans[300005];//保存八进制
int tmp1,len;
using namespace std; 
int main(){
    freopen("i.txt","r",stdin);
    Hash3[0][0][0]=0,Hash3[0][0][1]=1,Hash3[0][1][0]=2,Hash3[0][1][1]=3,Hash3[1][0][0]=4;
    Hash3[1][0][1]=5,Hash3[1][1][0]=6,Hash3[1][1][1]=7;
    cin>>n;
    while(n--){
        scanf("%s",arr);
        len=strlen(arr);
        for(int i=0;i<len;i++){
          if(arr[i]>=65){
            tmp[4*i]=Hash1[arr[i]-'A'][0];
            tmp[4*i+1]=Hash1[arr[i]-'A'][1];
            tmp[4*i+2]=Hash1[arr[i]-'A'][2];
            tmp[4*i+3]=Hash1[arr[i]-'A'][3];
          }
          else{
            tmp[4*i]=Hash2[arr[i]-'0'][0];
            tmp[4*i+1]=Hash2[arr[i]-'0'][1];
            tmp[4*i+2]=Hash2[arr[i]-'0'][2];
            tmp[4*i+3]=Hash2[arr[i]-'0'][3];
          }
        }  
        /*cout<<"len="<<len<<endl;
        for(int i=0;i<4*len;i++){
            cout<<tmp[i];
        }
        cout<<endl;*/
        int num=0,L=0;
        while(tmp[L++]==0) ;
        L--;
        //cout<<"L="<<L<<endl;
        for(int i=4*len-1;i>=L;i-=3){
            //cout<<"i="<<i<<" ";
            if(i-L==1)//消除前导0
                tmp1=tmp[i]+tmp[i-1]*2;
            else if(i-L==0) //消除前导0
                tmp1=tmp[i];
            else tmp1=Hash3[tmp[i-2]][tmp[i-1]][tmp[i]];
            //cout<<"tmp1="<<tmp1<<endl; 
            ans[num++]=tmp1;
        } 
        int i=num-1;  
        for(;i>=0;i--){
            printf("%d",ans[i]);
        }
        cout<<endl; 
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值