蓝桥杯练习系统_基础练习_十六进制转八进制

来源:互联网 发布:阿里云ddos 编辑:程序博客网 时间:2024/05/16 10:33

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

输入格式
  输入的第一行为一个正整数n (1<=n<=10)。
  接下来n行,每行一个由0~9、大写字母A~F组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。

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

  【注意
  输入的十六进制数不会有前导0,比如012A。
  输出的八进制数也不能有前导0。

样例输入
  2
  39
  123ABC

样例输出
  71
  4435274

  提示
  先将十六进制数转换成某进制数,再由某进制数转换成八进制。

思路:
  先将十六进制数转换为二进制数,再以3位二进制数为一个整体转化为一个八进制数。

最初代码:
#include <iostream>#include <string>using namespace std;int main(){int n;cin>>n;string o[n],h[n];for (int i=0;i<n;i++){cin>>h[i];}for (int j=0;j<n;j++){int lens=h[j].length();string str=h[j];string b[lens],b1[lens];char a[lens];int ha=lens/3;int hb=lens%3;for (int t=0;t<lens;t++){a[t]=str[t];}for (int k=0;k<lens;k++){switch (a[k]){case '0': b[k]="0000";break;case '1': b[k]="0001";break;case '2': b[k]="0010";break;case '3': b[k]="0011";break;case '4': b[k]="0100";break;case '5': b[k]="0101";break;case '6': b[k]="0110";break;case '7': b[k]="0111";break;case '8': b[k]="1000";break;case '9': b[k]="1001";break;case 'A': b[k]="1010";break;case 'B': b[k]="1011";break;case 'C': b[k]="1100";break;case 'D': b[k]="1101";break;case 'E': b[k]="1110";break;case 'F': b[k]="1111";break;}}string str1;for (int n=0;n<lens;n++){str1+=b[n];}int l=str1.length();int m=0;int hh=l/3+l%3;string s[hh];int t;for (t=l-1;t>1;t=t-3){s[m]+=str1[t-2];s[m]+=str1[t-1];s[m]+=str1[t];m++;}if (t==1 || t==0){m=m+1;int t1=2-t;if (t1=0){s[m]="00";s[m]+=str1[t];}if (t1=1){s[m]="0";s[m]+=str1[t-1];s[m]+=str1[t];}}char a1[m+1];for (int kk=m;kk>-1;kk--){if (s[kk]=="000"){if (kk=m);elsea1[kk]='0';}if (s[kk]=="001")a1[kk]='1';if (s[kk]=="010")a1[kk]='2';if (s[kk]=="011")a1[kk]='3';if (s[kk]=="100")a1[kk]='4';if (s[kk]=="101")a1[kk]='5';if (s[kk]=="110")a1[kk]='6';if (s[kk]=="111")a1[kk]='7';} string s2;for (int ll=0;ll<m+1;ll++){s2[ll]=a1[m-ll];cout<<s2[ll];}cout<<s2<<endl;}return 0;}

但是这个代码运行超时。
错误:二进制转八进制那里是将二进制全部转化完成存入字符串s2中,导致转化时的运行时间过长且占用空间太大。且代码太过繁杂。

成功代码:
#include <iostream>#include <string>using namespace std;int main(){int n;cin>>n;string h;for (int i=0;i<n;i++){cin>>h;string s;int lens=h.length();for (int k=0;k<lens;k++)//十六进制转二进制 {switch (h[k]){case '0': s+="0000";break;case '1': s+="0001";break;case '2': s+="0010";break;case '3': s+="0011";break;case '4': s+="0100";break;case '5': s+="0101";break;case '6': s+="0110";break;case '7': s+="0111";break;case '8': s+="1000";break;case '9': s+="1001";break;case 'A': s+="1010";break;case 'B': s+="1011";break;case 'C': s+="1100";break;case 'D': s+="1101";break;case 'E': s+="1110";break;case 'F': s+="1111";break;}}int lens2=s.length();if (lens2%3==1) //lens2判断是否为3的倍数,不是则s前面补0 {s="00"+s;}else if(lens2%3==2){s="0"+s;}int flag=0;//判断八进制数的首位是否为零 for (int j=0;j<lens2;j+=3)//三位二进制转为一位八进制 {int num=4*(s[j]-'0')+2*(s[j+1]-'0')+(s[j+2]-'0');if (num){flag=1;}if (flag){cout<<num;}}cout<<endl;}return 0;}

改正后的代码,修改了许多不必要的繁杂,将十六转二的字符串链接直接在switch函数中完成,用二进制的字符串长度对3求余来判断是否在二进制字符串前面加0。用flag判断八进制的首位是否为零。以三位二进制为一个集合转化为八进制并且直接输出,避免了整个八进制存入数组或string字符串中。

菜鸟一枚,不太会用文字描述。




0 0
原创粉丝点击