欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  网络运营

BASIC-12十六进制转换为八进制

程序员文章站 2022-03-30 09:58:08
题目问题描述  给定n个十六进制正整数,输出它们对应的八进制数。输入格式  输入的第一行为一个正整数n (1<=n<=10)。  接下来n行,每行一个由09、大写字母AF组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。输出格式  输出n行,每行为输入对应的八进制正整数。  【注意】  输入的十六进制数不会有前导0,比如012A。  输......

题目
问题描述
  给定n个十六进制正整数,输出它们对应的八进制数。
输入格式
  输入的第一行为一个正整数n (1<=n<=10)。
  接下来n行,每行一个由09、大写字母AF组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。
输出格式
  输出n行,每行为输入对应的八进制正整数。
  【注意】
  输入的十六进制数不会有前导0,比如012A。
  输出的八进制数也不能有前导0。
样例输入
  2
  39
  123ABC
样例输出
  71
  4435274
【提示】
  先将十六进制数转换成某进制数,再由某进制数转换成八进制。
解答:
该题思路比较简单,将输入的若干16进制数转换为2进制,再将每三位2进制数转换为一个八进制数即可。需要注意的是输出的数据首位若为0则不输出。
但是效率是个大问题,一直“运行超时”。经过以下几个版本的改进,终于通过了测评。
**题解一:**使用字符数组
这样做有两个明显的缺点:
1、需要为字符数组分配固定空间。
2、插入、取出操作特别麻烦。

#include <iostream>
using namespace std;
int main()
{
int n=0;
cin>>n;
char a[10][100000]; //原数字串,16进制 
char b[400000]; //2进制中转数字串
char c[300000]; //8进制目标数字串 
//获取准备转换的n个数 
for(int i=0;i<n;i++)
{
for(int j=0;j<1000;j++)
{
a[i][j]='\n';
} 
cin>>a[i];
}
int count[10];
for(int i=0;i<10;i++)
count[i]=0;
//转换 
for(int i=0;i<n;i++)
{
//计算出每一个数的长度 
for(int j=0;a[i][j]!='\n';j++)
count[i]++;
count[i]--;
//转换得到2进制数 
for(int j=0;j<count[i];j++)
{ 
if(a[i][j]<='9')
{
b[j*4]=(a[i][j]-'0')/8+48;
b[j*4+1]=((a[i][j]-'0')%8)/4+48;
b[j*4+2]=((a[i][j]-'0')%4)/2+48;
b[j*4+3]=((a[i][j]-'0')%2)/1+48;
}
else
{
b[j*4]=(a[i][j]-'A'+10)/8+48;
b[j*4+1]=((a[i][j]-'A'+10)%8)/4+48;
b[j*4+2]=((a[i][j]-'A'+10)%4)/2+48;
b[j*4+3]=((a[i][j]-'A'+10)%2)/1+48;
}
} 
int y=0;
if(count[i]*4%3>0)
y=(count[i]*4)/3+1;
else if(count[i]*4%3==0)
y=(count[i]*3)/4;
//转换得到八进制数 
for(int j=count[i]*4-1, m=0; m<y; j=j-3,m++) 
{
//cout<<"转换得到八进制"<<j<<endl;
if(j/3>0)
c[m] = (b[j]-'0') + (b[j-1]-'0')*2 + (b[j-2]-'0')*4+48;
else if(j-1==0)
c[m] = (b[j]-'0') +48;
else if(j-2==0)
c[m] = (b[j]-'0') + (b[j-1]-'0')*2 + 48; 
//cout<<"各项为:"<<b[j]<<b[j-1]<<b[j-2]<<" "<<endl;
} 
for(int j=y-1;j>=0;j--)
{
if(j==y-1&&c[j]==48)
;
else
cout<<c[j];
}
cout<<endl;
}
return 0; 
}

题解二:**使用字符串String
string提供了更多便捷实用的方法(如substr()截取字符串的某段、insert()在某个位置插入一段字符串、length()获取该字符串的长度等等),同时也避免了第一版代码所出现的问题。但是仍然运行超时,说明这两个版本的代码存在着共同的问题,那么就肯定是进制转换时做了太多无用的计算了——每一步我们都将ASCII码转换为整形数据,再用数学的方法计算出2/8进制数。

#include <iostream>
#include <string>
using namespace std;
int main()
{
int n=0; //记录输入数据的个数 
cin>>n;
string sixTeen[10];  //用来记录输入的数据 
for(int i=0;i<n;i++)
{
cin>>sixTeen[i];
}
string eight;//记录八进制数据 
char eig;
for(int i=0;i<n;i++)
{ 
string tow; //记录二进制数据 
//转换为二进制 
for(int j=0;j<sixTeen[i].length();j++)
{
if(sixTeen[i][j]<='9')
{
int now=sixTeen[i][j]-'0';  //由字符串的ASCII码得到数值 
eig=now/8+'0';
tow=tow+eig;         //对数值做计算并且再转换回ASCII码存入字符串 
eig=now%8/4+'0';
tow=tow+eig; 
eig=now%4/2+'0';
tow=tow+eig; 
eig=now%2+'0';
tow=tow+eig; 
}
else
{
int now=sixTeen[i][j]-'A'+10;
eig=now/8+'0';
tow=tow+eig;         //对数值做计算并且再转换回ASCII码存入字符串 
eig=now%8/4+'0';
tow=tow+eig; 
eig=now%4/2+'0';
tow=tow+eig; 
eig=now%2+'0';
tow=tow+eig; 
}
}
//cout<<tow<<endl; 
//转换为八进制
//首先补齐“0” 
int m=tow.length()%3;
if(m==1)
tow.insert(0,"00");
else if(m==2)
tow.insert(0,"0");
//进行转换 
for(int k=0;k<tow.length()/3;k++)
{
eig=(tow[k*3]-'0')*4+(tow[k*3+1]-'0')*2+(tow[k*3+2]);
eight=eight+eig;
} 
//输出最终的八进制数 
cout<<eight<<endl;
}
return 0;
}

**题解三:**使用Switch语句枚举
考虑到我们操作的对象只有字符串,16进制转2进制只用16种情况,而2进制转8进制也只有8种情况,所以只需要枚举所有情况即可。这样就可以避免坂本一、二代码共同的问题。

#include <iostream>
using namespace std;
int main()
{
int n=0; //记录输入数据的个数 
cin>>n;
string sixTeen[10];  //用来记录输入的数据 
for(int i=0;i<n;i++)
{
cin>>sixTeen[i];
} 
for(int i=0;i<n;i++)
{
string eight;//记录八进制数据
string tow; //记录二进制数据  
char eig;
 
//转换为二进制 
for(int j=0;j<sixTeen[i].length();j++)
{
switch(sixTeen[i][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;  
}
}
//转换为八进制
//首先补齐“0” 
int m=tow.length()%3;
if(m==1)
tow.insert(0,"00");
else if(m==2)
tow.insert(0,"0");
//进行转换 
if(!(tow[0]=='0'&&tow[1]=='0'&&tow[2]=='0'))
{
eig=(tow[0]-'0')*4+(tow[1]-'0')*2+(tow[2]);
eight=eight+eig;
}
 
for(int k=3;k<tow.length();k=k+3)
{
//eig=(tow[k*3]-'0')*4+(tow[k*3+1]-'0')*2+(tow[k*3+2]);
//eight=eight+eig;
 
if(tow.substr(k,3)=="000")
eight+="0";
else if(tow.substr(k,3)=="001")
eight+="1";
else if(tow.substr(k,3)=="010")
eight+="2";
else if(tow.substr(k,3)=="011")
eight+="3";
else if(tow.substr(k,3)=="100")
eight+="4"; 
else if(tow.substr(k,3)=="101")
eight+="5"; 
else if(tow.substr(k,3)=="110")
eight+="6"; 
else if(tow.substr(k,3)=="111")
eight+="7"; 
 
}
 
//输出最终的八进制数 
cout<<eight<<endl;
}
 
return 0;
}

本文地址:https://blog.csdn.net/qq_42403069/article/details/85962705

相关标签: 蓝桥杯