基础练习 十六进制转八进制
时间限制:1.0s 内存限制:512.0MB
问题描述
给定n个十六进制正整数,输出它们对应的八进制数。
输入格式
输入的第一行为一个正整数n (1<=n<=10)。
接下来n行,每行一个由0~9、大写字母A~F组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。
输出格式
输出n行,每行为输入对应的八进制正整数。
【注意】
输入的十六进制数不会有前导0,比如012A。
输出的八进制数也不能有前导0。
样例输入
2
39
123ABC
样例输出
71
4435274
【提示】
先将十六进制数转换成某进制数,再由某进制数转换成八进制。
整体思路:(1)先将所输16进制数转化为2进制数,再将2进制数转化为8进制数。每4位2进制数转化1位16进制数,每3位2进制数转化1位8进制数。我是同过8421码进行16->2->8的,这里就需要牢记每个16进制数对应的10进制数和每个10进制数对应的2进制数了。详细代码请看下面(2)在进行16转2时还有一种方法是我看到别人写的代码 利用switch语句 每个16进制数直接手动转化。例如 (左为16进制数右为对应的2进制数)0——0000; 1——0001;2——0010;3——0011;4——0100;5——0101;6——0110;7——0111;8——1000;9——1001;A——1010;B——1011;C——1100;D——1101;E——1110;F——1111;
#include <iostream>
#include <stack>
#include <string.h>
#include <stdio.h>
#include<math.h>
using namespace std;
int main()
{
int n,l,b[400000],c,x;//用来存储所转化的2进制数
stack <int> s;
char a[100000];//用来存储输入的16进制数
cin>>n;
while(n!=0)
{
l=0;
scanf("%s",a);
for(int i=strlen(a)-1;i>=0;i--)//将输入的16进制数转化为2进制数,这里我先转化成10进制数 在转化为2进制数。
{
if(a[i]>='A'&&a[i]<='F')
x=a[i]-'A'+10;//当所输入为A~F时,所输入字母减去A再加上10 便是所表示的10进制数。
else x=a[i]-48;//当输入为0~9时直接减去48或'0'就是相应的整数。
for(int j=0;j<4;j++)//通过8421码我们知道16进制的每个数需用4位2进制数表示所以进行4次循环。
{
c=x%2;
x=x/2;
b[l++]=c;
}
}
int k=-1;//k用来表示几次幂,和间接计数位数。
int sum=0;
for(int i=0;i<l;i++)
{
k++;
sum+=b[i]*pow(2,k);
if(k==2||i==l-1&&sum!=0)//再将b数组3个3个按序分组,这里的(i==l-1&&sum!=0)是为了判断是否为尾元素且不满三位并且防止输出前导零。之前一直不通过就是这个条件写的不对。
{
k=-1;
s.push(sum);//用栈存储所转化的8进制。
sum=0;
}
}
while(s.empty()!=true)
{
cout<<s.top();
s.pop();
}
cout<<endl;
n--;
}
return 0;
}