本程序处理的情况是当十六进制数很大的时候,比如有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;
}