实践编程自我检错_蓝桥杯_ 基础练习 十六进制转八进制
来源:互联网 发布:软件开发课程 编辑:程序博客网 时间:2024/06/05 15:21
问题:
问题描述
给定n个十六进制正整数,输出它们对应的八进制数。输入格式
输入的第一行为一个正整数n (1<=n<=10)。
接下来n行,每行一个由0~9、大写字母A~F组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。
输出格式
输出n行,每行为输入对应的八进制正整数。
【注意】
输入的十六进制数不会有前导0,比如012A。
输出的八进制数也不能有前导0。
样例输入
2
39
123ABC
样例输出
71
4435274
【提示】
先将十六进制数转换成某进制数,再由某进制数转换成八进制。
最初思路:
定义n,输入n,定义char **x;char **b;char **o;
最外围做一个n次的for循环,以int i控制,循环内所做的工作如下
以字符串形式输入一个十六进制数,用x[i]把输入的16进制数以字符串的形式存储下来
用while做外循环把字符串中的字符一个一个的读出来并用switch识别,每个十六进制字符转化为四个二进制字符并存储到b[i]下,当循环到'\0'即为x所指字符串读完,结束while
然后先通过strlen计算各个字符串长度,长度不是三的倍数的在字符串最前加0
然后做一个循环,每次循环在b所指的一条字符串中读取3个字符并通过识别转化为对应的八进制数以字符的形式存到o[i]下,循环到'\0'即为b所指字符串读完,结束循环
用puts输出o[i]所指字符串,本次for循环结束,i++,继续下一次
n次for循环完成后,程序结束
实践编程中遇到的问题:
#include <stdio.h>#include <string.h>#include <stdlib.h>int main(){int n;scanf("%d\n",&n);char **x=(char **)malloc(sizeof(char *)*n);char **b=(char **)malloc(sizeof(char *)*n);char **o=(char **)malloc(sizeof(char *)*n);for(int i=0;i<n;i++){x[i]=new char[100001];b[i]=new char[140000];o[i]=new char[400004];}return 0;}
问题原因:所使用的字符指针数组未进行动态内存分配就在使用,是野指针,进行两次动态内存分配后可解决
存在疑惑:这样的话用字符数组岂不是更方便吗,反正都要提前分配那么大的内存才能用,字符数组还更适合访问,关于指针的使用优点和细节不清晰有待加深
#include <stdio.h>#include <string.h>#include <stdlib.h>int main(){int n;scanf("%d\n",&n);char **x=(char **)malloc(sizeof(char *)*n);char **b=(char **)malloc(sizeof(char *)*n);char **o=(char **)malloc(sizeof(char *)*n);for(int i=0;i<n;i++){x[i]=new char[100001];b[i]=new char[140000];o[i]=new char[400004];}char *p,*q,*m;int a;for(int i=0;i<n;i++){p=x[i];q=b[i];m=o[i];a=0;scanf("%s",x[i]);while(p[a]!='\0'){switch(p[a]) { case '0': strcat(q,"0000"); break; case '1': strcat(q,"0001"); break; case '2': strcat(q,"0010"); break; case '3': strcat(q,"0011"); break; case '4': strcat(q,"0100"); break; case '5': strcat(q,"0101"); break; case '6': strcat(q,"0110"); break; case '7': strcat(q,"0111"); break; case '8': strcat(q,"1000"); break; case '9': strcat(q,"1001"); break; case 'A': strcat(q,"1010"); break; case 'a': strcat(q,"1010"); break; case 'B': strcat(q,"1011"); break; case 'b': strcat(q,"1011"); break; case 'C': strcat(q,"1100"); break; case 'c': strcat(q,"1100"); break; case 'D': strcat(q,"1101"); break; case 'd': strcat(q,"1101"); break; case 'E': strcat(q,"1110"); break; case 'e': strcat(q,"1110"); break; case 'F': strcat(q,"1111"); break; case 'f': strcat(q,"1111"); break; default:printf("输入的16进制数有错误!请重新输入!"); exit(1);break; } a++;}printf("%s\n",q);}return 0;}问题:转换后的二进制字符串首部都多了三个乱码,经排除法检查发现是new的问题,改用
x[i]=(char *)malloc(sizeof(char *)*100001);
b[i]=(char *)malloc(sizeof(char *)*140000);
o[i]=(char *)malloc(sizeof(char *)*400004);
不过暂时不知道为什么用new会错,待解决
#include <stdio.h>#include <string.h>#include <stdlib.h>int main(){int n;scanf("%d\n",&n);char **x=(char **)malloc(sizeof(char *)*n);char **b=(char **)malloc(sizeof(char *)*n);char **o=(char **)malloc(sizeof(char *)*n);for(int i=0;i<n;i++){x[i]=(char *)malloc(sizeof(char *)*100001);b[i]=(char *)malloc(sizeof(char *)*140000);o[i]=(char *)malloc(sizeof(char *)*400004);}char *p,*q,*m;int a;for(int i=0;i<n;i++){p=x[i];q=b[i];m=o[i];a=0;scanf("%s",x[i]);while(p[a]!='\0'){switch(p[a]) { case '0': strcat(q,"0000"); break; case '1': strcat(q,"0001"); break; case '2': strcat(q,"0010"); break; case '3': strcat(q,"0011"); break; case '4': strcat(q,"0100"); break; case '5': strcat(q,"0101"); break; case '6': strcat(q,"0110"); break; case '7': strcat(q,"0111"); break; case '8': strcat(q,"1000"); break; case '9': strcat(q,"1001"); break; case 'A': strcat(q,"1010"); break; case 'a': strcat(q,"1010"); break; case 'B': strcat(q,"1011"); break; case 'b': strcat(q,"1011"); break; case 'C': strcat(q,"1100"); break; case 'c': strcat(q,"1100"); break; case 'D': strcat(q,"1101"); break; case 'd': strcat(q,"1101"); break; case 'E': strcat(q,"1110"); break; case 'e': strcat(q,"1110"); break; case 'F': strcat(q,"1111"); break; case 'f': strcat(q,"1111"); break; default:printf("输入的16进制数有错误!请重新输入!"); exit(1);break; } a++;}printf("%s\n",q);if(strlen(q)%3==2) strcat(q,"0");if(strlen(q)%3==1) strcat(q,"00");printf("%s\n",q);}return 0;}问题:不知道怎么在字符串首加字符,上面的最后是加在了字符串尾部
char *t=(char *)malloc(sizeof(char *)*140000);if(strlen(b[i])%3==2){strcat(t,"0");strcat(t,b[i]);strcpy(b[i],t);}if(strlen(b[i])%3==1){strcat(t,"00");strcat(t,b[i]);strcpy(b[i],t);}解决方法:以字符串t做中转达成目的,对字符串操作的函数不够熟悉
#include <stdio.h>#include <string.h>#include <stdlib.h>int main(){int n;scanf("%d\n",&n);char **x=(char **)malloc(sizeof(char *)*n);char **b=(char **)malloc(sizeof(char *)*n);char **o=(char **)malloc(sizeof(char *)*n);for(int i=0;i<n;i++){x[i]=(char *)malloc(sizeof(char *)*100001);b[i]=(char *)malloc(sizeof(char *)*140000);o[i]=(char *)malloc(sizeof(char *)*400004);}char *p,*q,*m;int a;for(int i=0;i<n;i++){p=x[i];q=b[i];m=o[i];a=0;scanf("%s",x[i]);while(p[a]!='\0'){switch(p[a]) { case '0': strcat(b[i],"0000"); break; case '1': strcat(b[i],"0001"); break; case '2': strcat(b[i],"0010"); break; case '3': strcat(b[i],"0011"); break; case '4': strcat(b[i],"0100"); break; case '5': strcat(b[i],"0101"); break; case '6': strcat(b[i],"0110"); break; case '7': strcat(b[i],"0111"); break; case '8': strcat(b[i],"1000"); break; case '9': strcat(b[i],"1001"); break; case 'A': strcat(b[i],"1010"); break; case 'a': strcat(b[i],"1010"); break; case 'B': strcat(b[i],"1011"); break; case 'b': strcat(b[i],"1011"); break; case 'C': strcat(b[i],"1100"); break; case 'c': strcat(b[i],"1100"); break; case 'D': strcat(b[i],"1101"); break; case 'd': strcat(b[i],"1101"); break; case 'E': strcat(b[i],"1110"); break; case 'e': strcat(b[i],"1110"); break; case 'F': strcat(b[i],"1111"); break; case 'f': strcat(b[i],"1111"); break; default:printf("输入的16进制数有错误!请重新输入!"); exit(1);break; } a++;}char *t=(char *)malloc(sizeof(char *)*140000);if(strlen(b[i])%3==2){strcat(t,"0");strcat(t,b[i]);strcpy(b[i],t);}if(strlen(b[i])%3==1){strcat(t,"00");strcat(t,b[i]);strcpy(b[i],t);}//至此十六进制转换为二进制完毕 a=0;char s='0';while(*q){if(*q==s){q++;if(*q==s){q++;if(*q==s) strcat(o[i],"0");else strcat(o[i],"1");}else {q++;if(*q==s) strcat(o[i],"2");else strcat(o[i],"3");}}else {q++;if(*q==s){q++;if(*q==s) strcat(o[i],"4");else strcat(o[i],"5");}else {q++;if(*q==s) strcat(o[i],"6");else strcat(o[i],"7");}}q++;}}for(int j=0;j<n;j++){printf("%s\n",o[j]);}return 0;}最终代码,运行成功,结果符合,不过运行超时,于是改良
#include <stdio.h>#include <string.h>#include <stdlib.h>char x[10][100001];char b[10][140000];char o[10][400004];int main(){int n,i,j;scanf("%d\n",&n);for(i=0;i<n;i++){j=0;scanf("%s",x[i]);while(x[i][j]){switch(x[i][j]) { case '0': strcat(b[i],"0000"); break; case '1': strcat(b[i],"0001"); break; case '2': strcat(b[i],"0010"); break; case '3': strcat(b[i],"0011"); break; case '4': strcat(b[i],"0100"); break; case '5': strcat(b[i],"0101"); break; case '6': strcat(b[i],"0110"); break; case '7': strcat(b[i],"0111"); break; case '8': strcat(b[i],"1000"); break; case '9': strcat(b[i],"1001"); break; case 'A': strcat(b[i],"1010"); break; case 'a': strcat(b[i],"1010"); break; case 'B': strcat(b[i],"1011"); break; case 'b': strcat(b[i],"1011"); break; case 'C': strcat(b[i],"1100"); break; case 'c': strcat(b[i],"1100"); break; case 'D': strcat(b[i],"1101"); break; case 'd': strcat(b[i],"1101"); break; case 'E': strcat(b[i],"1110"); break; case 'e': strcat(b[i],"1110"); break; case 'F': strcat(b[i],"1111"); break; case 'f': strcat(b[i],"1111"); break; default:printf("输入的16进制数有错误!请重新输入!"); exit(1);break; } j++;}j=0;if(strlen(b[i])%3==2){if(b[i][j]=='0'){j++;if(b[i][j]=='0') {}else {strcat(o[i],"1");}}else {j++;if(b[i][j]=='0') {strcat(o[i],"2");}else {strcat(o[i],"3");}}j++;}if(strlen(b[i])%3==1){if(b[i][j]=='0') {}else {strcat(o[i],"1");}j++;}while(b[i][j]){if(b[i][j]=='0'){j++;if(b[i][j]=='0'){j++;if(b[i][j]=='0') {}else {strcat(o[i],"1");}}else {j++;if(b[i][j]=='0') {strcat(o[i],"2");}else {strcat(o[i],"3");}}}else {j++;if(b[i][j]=='0'){j++;if(b[i][j]=='0') {strcat(o[i],"4");}else {strcat(o[i],"5");}}else {j++;if(b[i][j]=='0') {strcat(o[i],"6");}else {strcat(o[i],"7");}}}j++;}}for(i=0;i<n;i++){printf("%s\n",o[i]);}return 0;}
大幅修改,仍然运行超时,不能理解,switch和if else应该是很节省运行时间的吧,毕竟在我看来它们都通过条件判断选择执行的一部分代码
完全修改思路,既然确定是十六进制转八进制,那可以先补全输入的字符串为3的整数被,然后每循环一次取出3个十六进制数转化为4个八进制数:
#include <iostream> #include <string>using namespace std;int main(){string x,o; int n,i; cin>>n; for(i=0;i<n;i++){cin>>x;int len=x.length();if(len%3){string x2="0";string x1="00";len%3==2?x=x2+x:x=x1+x;}int pos=0;while(pos!=len){string t=x.substr(pos,3);pos+=3;int a=0;int m[3]={256,16,1};for(int j=0;j<3;j++){t[j]<60?a+=(t[j]-48)*m[j]:t[j]<95?a+=(t[j]-55)*m[j]:a+=(t[j]-87)*m[j];}t.clear();t[j]} } return 0; }已把那三个十六进制数利用ascii码转换成对应的十进制数,然后怎么转化为八进制的字符存储到string o呢.....
经实际运行substr处抛出异常,不知具体原因,等我看看源代码后续更改,或者求看到这博客的大神解答
异常无法处理,换实现方法:
#include <iostream> #include <string>using namespace std;int main(){ string x,o=new char[140000]; int n,i; cin>>n; for(i=0;i<n;i++){cin>>x;int len=x.length();if(len%3){string x2="0";string x1="00";len%3==2?x=x2+x:x=x1+x;}int xpos=0;int opos=0;while(xpos!=len){int a=0;int m[3]={256,16,1};for(int j=0;j<3;j++){x[xpos]<60?a+=(x[xpos]-48)*m[j]:x[xpos]<95?a+=(x[xpos]-55)*m[j]:a+=(x[xpos]-87)*m[j];xpos++;}o[opos]=a/512+48; o[opos+1]=(a/64)%8+48; o[opos+2]=(a/8)%8+48; o[opos+3]=a%8+48;opos+=4;}o[opos+1]='\0';if(o[0]==48)if(o[1]==48){o.erase(0,2);}else{o.erase(0,1);} } return 0; }
未知错误...
经排查是我不应该直接对那片内存空间存储数据,这样会造成string类中的lenth等内部数据与真实数据不一样,应该调用string类自己的函数来存储数据
另外我发现当我用new分配很大的内存空间时总会在前面莫名出现一段乱码如下:
一直都是p和一个笑脸,很奇怪的乱码,留个坑以后探究一下new的原型再回来完善
另外最后的代码出来了:
#include <iostream> #include <string>using namespace std;int main(){ int n,i; cin>>n; string o[n]; for(i=0;i<n;i++){ string x;cin>>x;int len=x.length();if(len%3){string x2="0";string x1="00";len%3==2?x=x2+x:x=x1+x;}int xpos=0;int m[3]={256,16,1};while(x[xpos]){int a=0;for(int j=0;j<3;j++){x[xpos]<60?a+=(x[xpos]-48)*m[j]:x[xpos]<95?a+=(x[xpos]-55)*m[j]:a+=(x[xpos]-87)*m[j];xpos++;}char o1;o1=a/512+48;o[i]+=o1; o1=(a/64)%8+48;o[i]+=o1; o1=(a/8)%8+48;o[i]+=o1;o1=a%8+48;o[i]+=o1;}if(o[i][0]==48){if(o[i][1]==48){if(o[i][2]==48){o[i].erase(0,3);}else{o[i].erase(0,2);}}else{o[i].erase(0,1);} }}for(i=0;i<n;i++){ cout<<o[i]<<endl;} return 0; }
通过OJ,成功搞定一道.......
缺漏知识:
1.指针必须在赋初值后使用,任何类型指针
2.gets(s)函数与 scanf("%s",&s) 相似,但不完全相同,使用scanf("%s",&s) 函数输入字符串时存在一个问题,就是如果输入了空格会认为字符串结束,空格后的字符将作为下一个输入项处理,但gets()函数将接收输入的整个字符串直到遇到换行为止。
1.不同点:
2.相同点:
3.用malloc申请的空间在使用完毕后要free掉,用new申请的要delete掉,申请过后最好判断一下是否申请成功,失败则提示并异常退出,另外new是C++中的
4.上面红色的各个坑以后慢慢填
0 0
- 实践编程自我检错_蓝桥杯_ 基础练习 十六进制转八进制
- 蓝桥杯练习系统_基础练习_十六进制转八进制
- 蓝桥杯:基础练习 十六进制转八进制
- "蓝桥杯“基础练习:十六进制转八进制
- 蓝桥杯 【基础练习】 十六进制转八进制
- 蓝桥杯:基础练习 十六进制转八进制
- 蓝桥杯基础练习--十六进制转八进制
- 【蓝桥杯】基础练习 十六进制转八进制
- 蓝桥杯基础练习 十六进制转八进制
- 基础练习-十六进制转八进制 -JAVA蓝桥杯
- 1501091239-蓝桥杯-基础练习 十六进制转八进制
- 蓝桥杯 基础练习 十六进制转八进制
- 蓝桥杯_ 基础练习 十六进制转八进制
- "蓝桥杯“基础练习:十六进制转八进制
- 蓝桥杯-基础练习12 十六进制转八进制
- 蓝桥杯-基础练习-十六进制转八进制
- 蓝桥杯:基础练习 十六进制转八进制
- 蓝桥杯 基础练习 十六进制转八进制
- 《机器学习实战》——读书笔记1
- 插入空行的思路
- java集合系列——List集合之Vector介绍(四)
- Java对象的祖宗Object类
- Atitit 性能指标与性能提升的5个原则与性能提升模型
- 实践编程自我检错_蓝桥杯_ 基础练习 十六进制转八进制
- 简单常用时间格式化工具类
- SSH+Dubbo+zookeeper集成
- Mybatis 简单查询
- log4j编写一个单独的日志输出类
- Android Studio使用apklib
- Android仿斗鱼滑动登录验证
- 在ccs7下进行DM6467的开发(2):在Linux下安装ccs
- Verilog/CPLD代码之1s定时LED跑马灯