问题描述
给定n个十六进制正整数,输出它们对应的八进制数。
输入格式
输入的第一行为一个正整数n (1<=n<=10)。
接下来n行,每行一个由0~9、大写字母A~F组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。
输出格式
输出n行,每行为输入对应的八进制正整数。
【注意】
输入的十六进制数不会有前导0,比如012A。
输出的八进制数也不能有前导0。
样例输入
2
39
123ABC
样例输出
71
4435274
【提示】
先将十六进制数转换成某进制数,再由某进制数转换成八进制。
题目提示了使用一种进制作为中转,很容易想到先转为十进制,然后再转为八进制,但是要注意的是,当十六进制数很大时,转为十进制时使用的整数类型会无法存储下这么大的数,所以正确的做法应该是先转为二进制,然后再转为八进制。
#include<iostream> using namespace std; #include<math.h> int* num1; //存储二进制 int* num2; //存储八进制 int charToint(char c) {if(c>='0'&&c<='9')return c-'0';return 10+c-'A'; } //十六进制转二进制 int shiliuToer(string s) {int n=s.length();for(int i=0;i<n;i++){int x=charToint(s[i]);for(int j=3;j>=0;j--){num1[i*4+j]=x%2;x=x/2;}}//去除前导0int i=0;while(i<4*n&&num1[i]==0){i++;}num1=num1+i;return 4*n-i; } //二进制转八进制 int erToba(int n) {int i=n-1;int count=0;int a,b,c;while(i>=0){a=num1[i--];if(i>=0)b=num1[i--];else b=0;if(i>=0)c=num1[i--];else c=0;num2[count++]=a+b*2+c*4;}return count; } int main() {int n;cin>>n;num1=new int[500000]; //十进制num2=new int[500000]; //八进制string s;for(int i=0;i<n;i++){cin>>s;if(s=="0"){cout<<0<<endl;continue;}int n1=shiliuToer(s); //十六进制转成二进制int n2=erToba(n1); //二进制转成八进制for(int j=n2-1;j>=0;j--){cout<<num2[j];}cout<<endl;}return 0; }
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283