C++-蓝桥杯基础训练-第12题-16进制转8进制高效算法
来源:互联网 发布:算法设计与分析 视频 编辑:程序博客网 时间:2024/05/22 11:58
题目:
解答:
该题思路比较简单,将输入的若干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);elsecout<<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;}
总结:
1、为了提高程序效率,除了采用时间复杂度更低的算法外,有时还可以“以空间换时间”。
2、该复习复习,学过的东西都忘了,比如“a += 1;”和“a = a + 1;”两个式子虽然结果相同,但是后者耗时更多一些。
0 0
- C++-蓝桥杯基础训练-第12题-16进制转8进制高效算法
- 算法基础训练题(一)
- 算法基础训练题(一)
- 算法基础训练题(一)
- 算法基础训练题(一)
- 算法基础训练题(二)
- 算法基础训练题(二)
- C++ 蓝桥杯基础训练 10进制转16进制
- 蓝桥杯 基础训练题
- 蓝桥杯基础训练图形显示(c/c++)
- 【基础训练】HDOJ2031进制转换
- 第8章 高效算法设计读书笔记
- 蓝桥杯 基础训练
- 算法基础训练(二)
- 高效算法之贪心算法(第16章)
- 推荐系统:技术、评估及高效算法 第12章
- 推荐系统:技术、评估及高效算法 第8章
- c语言程序设计现代算法第8章第9题
- 为啥学前端的人那么多,但好的前端工程师却很难找
- Java中的注释
- 考试4
- Apache httpd设置HTTPS双向认证
- 九度OJ-1194-八进制
- C++-蓝桥杯基础训练-第12题-16进制转8进制高效算法
- 操作格子 线段树
- Android开发的内存问题
- poj1039 计算几何-交点,叉积
- Effective C++ - Accustoming Yourself to C++
- 开始学wxpython啦~~~~~
- Tomcat单向Https验证搭建,亲自实现与主流浏览器、Android/iOS移动客户端安全通信
- XML相关操作
- OpenStack计费组件 - Cloudkitty介绍