天天看点

算法基础—十六进制转八进制进制转换

进制转换

       六进制,八进制,二进制,十进制之间的转换是最基本的能力,但有些题目对于新手来说有点难以理解,我拿出一道题来拓展的讲一讲。

进制转换方法:

   1、二进制转八进制——取每三位按权相加。

   2、二进制转十六进制—取每四位按权相加。

   3、二进制转十进制——按权相加。

   4、八进制转二进制——熟练掌握二进制转换,做到看到一个数直

        接写它的二进制数,再将二进制相连接,不足三位补0,去前导

        0。

   6、十六进制转二进制—同八进制,注意不足四位补0,去前导0.

   7、十进制转八进制——除八取余。

   8、十进制转十六进制—除十六取余。

   9、十六进制和八进制转十进制通过二进制转换。

问题描述

给定n个十六进制正整数,输出它们对应的八进制数。

输入格式

输入的第一行为一个正整数n (1<=n<=10)。

接下来n行,每行一个由0~~9、大写字母A~F组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。

输出格式

输出n行,每行为输入对应的八进制正整数。

【注意】

输入的十六进制数不会有前导0,比如012A。

输出的八进制数也不能有前导0。

样例输入

2

39

123ABC

样例输出

71

4435274

转换进制最简单的方法是使用"iostream"库函数下的格式控制符dec、hex、oct。

#include <iostream>
using namespace std;

int main()
{
	int n;
	cin>>hex>>n;
	cout<<oct<<n;
	
	return 0;
}
           

评测一看:错误。回头一看,100000位十六进制,还是老老实实打吧。

有两条路可以走,字符串和数组。我第一感觉字符串想起来简单,直接下手字符串。

string sixteen;
		cin>>sixteen;
		string tow;
		string eight;
           

首先是十六进制转二进制,我原来打的有点烦了。这是网上传的比较广的一个方法,

for(int j=0; j<sixteen.length(); j++)
		{
			switch(sixteen[j])
			{
				case '0':tow+="0000";break;
				case '1':tow+="0001";break;
				case '2':tow+="0010";break;
				case '3':tow+="0011";break;
				case '4':tow+="0100";break;
				case '5':tow+="0101";break;
				case '6':tow+="0110";break;
				case '7':tow+="0111";break;
				case '8':tow+="1000";break;
				case '9':tow+="1001";break;
				case 'A':tow+="1010";break;
				case 'B':tow+="1011";break;
				case 'C':tow+="1100";break;
				case 'D':tow+="1101";break;
				case 'E':tow+="1110";break;
				case 'F':tow+="1111";break;
				default:break;
			}
		}
           

二进制转八进制是从右往左每3位按权相加,不足补0。所以我们在转换之前先要确保它是3的整除数。

if(tow.length()%3==1)//1
			tow="00"+tow;	//001
		if(tow.length()%3==2)
			tow="0"+tow;
           

因为要确保不能存在前导0,所以我们拿出前三个来判断他们相加是不是等于0,即他们三个等不等于0:

if(!(tow[0]=='0'&&tow[1]=='0'&&tow[2]=='0'))
		{
			char temp;
			temp = (tow[0]-'0')*4+(tow[1]-'0')*2+tow[2];
			eight += temp;
		}
           

‘10’+5, 即‘10’的ASCLL码加上5, 即‘15’的ASCLL码

如果我是char temp=15,那就是ASCLL码为15的值。

然后对后面的进行转换:

for(int j=3; j<tow.length(); j+=3)
		{
			eight+=(tow[j]-'0')*4+(tow[j+1]-'0')*2+tow[j+2];
		}
           

tow[j]是一个字符型,它减去‘0’实际上就是它的ASCLL码值减去‘0’的ASCLL码值,作为数字的它,即等于它的整数型。

也可以用一种更可观的方式,就是码字要多了点:

for(int j=3; j<tow.length(); j+=3)
		{
			if(tow.substr(j,3)=="000")
				eight+="0";
			else if(tow.substr(j,3)=="001")
				eight+="1";
			else if(tow.substr(j,3)=="010")
				eight+="2";
			else if(tow.substr(j,3)=="011")
				eight+="3";
			else if(tow.substr(j,3)=="100")
				eight+="4";
			else if(tow.substr(j,3)=="101")
				eight+="5";
			else if(tow.substr(j,3)=="110")
				eight+="6";
			else if(tow.substr(j,3)=="111")
				eight+="7";
		}
           

这是我做的完整的代码,一开始我以为是输入完十六进制后再一起输出八进制,后来发现输入一个输出一个和一起输入一起输出都是对的。

#include <iostream>
using namespace std;

int main()
{
	int n;
	cin>>n;
	for(int i=0; i<n; i++)
	{	
		string tow;
		string sixteen;
		string eight;
		cin>>sixteen;
		for(int j=0; j<sixteen.length(); j++)
		{
			switch(sixteen[j])
			{
				case '0':tow+="0000";break;
				case '1':tow+="0001";break;
				case '2':tow+="0010";break;
				case '3':tow+="0011";break;
				case '4':tow+="0100";break;
				case '5':tow+="0101";break;
				case '6':tow+="0110";break;
				case '7':tow+="0111";break;
				case '8':tow+="1000";break;
				case '9':tow+="1001";break;
				case 'A':
				case 'a':tow+="1010";break;
				case 'B':
				case 'b':tow+="1011";break;
				case 'C':
				case 'c':tow+="1100";break;
				case 'D':
				case 'd':tow+="1101";break;
				case 'E':
				case 'e':tow+="1110";break;
				case 'F':
				case 'f':tow+="1111";break;
			}
		}
		if(tow.length()%3==1)
			tow="00"+tow;
		if(tow.length()%3==2)
			tow="0"+tow;
		if(!(tow[0]=='0'&&tow[1]=='0'&&tow[2]=='0'))
		{
			char temp;
			temp = (tow[0]-'0')*4+(tow[1]-'0')*2+tow[2];
			eight += temp;
		}
		for(int j=3; j<tow.length(); j+=3)
		{
			eight+=(tow[j]-'0')*4+(tow[j+1]-'0')*2+tow[j+2];
		}
		cout<<eight<<endl;
	}
	return 0;
}
           

继续阅读