以下自己写的,代码较长,但是我觉得好理解。会了这个的话,下面几题的十六进制转十进制什么的就很容易了。
PS:本章没有使用数据结构的知识,不涉及栈,链表等.
试题 基础练习 十六进制转八进制
资源限制
时间限制:1.0s 内存限制:512.0MB
问题描述
给定n个十六进制正整数,输出它们对应的八进制数。
输入格式
输入的第一行为一个正整数n (1<=n<=10)。
接下来n行,每行一个由0~9、大写字母A~F组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。
输出格式
输出n行,每行为输入对应的八进制正整数。
【注意】
输入的十六进制数不会有前导0,比如012A。
输出的八进制数也不能有前导0。
样例输入
2
39
123ABC
样例输出
71
4435274
【提示】
先将十六进制数转换成某进制数,再由某进制数转换成八进制。
全部代码
#include <iostream>
//#include<iomanip>//setw()函数使用,定义输入的个数。
#include <string.h>
//#include<cmath>
using namespace std;
void eight_(string Arrx){//二进制字符串转成8进制字符串
int n;
n=Arrx.length();
if(n%3==1){//判断Arrx内字符的个数不能被3整除,余数多出了1位 ,补2个0
Arrx="00"+Arrx;
}
else if(n%3==2){//判断Arrx内字符的个数不能被3整除,余数多出了2位 ,补1个0
Arrx="0"+Arrx;
}
n=Arrx.length();
char Arry_eight[n];
strcpy(Arry_eight,Arrx.c_str());
int i,j;
i=n/3;//8进制位数
j=i-1;//字符数组对应的8进制位数
int x,y,z;
if(Arry_eight[0]=='0'&&Arry_eight[1]=='0'&&Arry_eight[2]=='0'){
j-- ;
i--;
}
char Arrx_eight[i];
x=n-1;
y=n-2;
z=n-3;
for(int o=i;o>0;o--){
if(Arry_eight[z]=='0'&&Arry_eight[y]=='0'&&Arry_eight[x]=='1'){
Arrx_eight[j]='1';
}
else if(Arry_eight[z]=='0'&&Arry_eight[y]=='1'&&Arry_eight[x]=='0'){
Arrx_eight[j]='2';
}
else if(Arry_eight[z]=='0'&&Arry_eight[y]=='1'&&Arry_eight[x]=='1'){
Arrx_eight[j]='3';
}
else if(Arry_eight[z]=='1'&&Arry_eight[y]=='0'&&Arry_eight[x]=='0'){
Arrx_eight[j]='4';
}
else if(Arry_eight[z]=='1'&&Arry_eight[y]=='0'&&Arry_eight[x]=='1'){
Arrx_eight[j]='5';
}
else if(Arry_eight[z]=='1'&&Arry_eight[y]=='1'&&Arry_eight[x]=='0'){
Arrx_eight[j]='6';
}
else if(Arry_eight[z]=='1'&&Arry_eight[y]=='1'&&Arry_eight[x]=='1'){
Arrx_eight[j]='7';
}
else if(Arry_eight[z]=='0'&&Arry_eight[y]=='0'&&Arry_eight[x]=='0' ){
Arrx_eight[j]='0';
}
j--;
x-=3;
y-=3;
z-=3;
}
for(int p=0;p<i;p++){//输出8对应的8进制数
cout<<Arrx_eight[p];
}
cout<<endl;
}
void A_F_2(char num[],int n){//转换成二进制
string Arry[n];
string Arrx;
int andd=0;
for(int i=0;i<n;i++){
if(num[i]=='0'||num[i]=='1'||num[i]=='2'||num[i]=='3'||num[i]=='4'||num[i]=='5'||num[i]=='6'||num[i]=='7'||num[i]=='8'||num[i]=='9'){
if(num[i]=='0'&&i!=0){
Arry[i]="0000";
}
else if(num[i]=='1'){
Arry[i]="0001";
}
else if(num[i]=='2'){
Arry[i]="0010";
}
else if(num[i]=='3'){
Arry[i]="0011";
}
else if(num[i]=='4'){
Arry[i]="0100";
}
else if(num[i]=='5'){
Arry[i]="0101";
}
else if(num[i]=='6'){
Arry[i]="0110";
}
else if(num[i]=='7'){
Arry[i]="0111";
}
else if(num[i]=='8'){
Arry[i]="1000";
}
else if(num[i]=='9'){
Arry[i]="1001";
}
}
else if (num[i]=='A'||num[i]=='a'){
Arry[i]="1010";
}
else if (num[i]=='B'||num[i]=='b'){
Arry[i]="1011";
}
else if (num[i]=='C'||num[i]=='c'){
Arry[i]="1100";
}
else if (num[i]=='D'||num[i]=='d'){
Arry[i]="1101";
}
else if (num[i]=='E'||num[i]=='e'){
Arry[i]="1110";
}
else if (num[i]=='F'||num[i]=='f'){
Arry[i]="1111";
}
}//还是转换成十六进制字符串
for(int i=0;i<n;i++){//十六进制字符串合并
Arrx+=Arry[i];
}
eight_(Arrx);
}
int main(int argc, char** argv) {
int n;
cin>>n;
string aa[n];
for(int i=0;i<n;i++){//输入
cin>>aa[i];
}
for(int i=0;i<n;i++){//将每个字符串转成字符数组进行定位
string a=aa[i];
char c[aa[i].length()];
strcpy(c,a.c_str());//把字符串s转换成字符指针,string转换char* ,然后再将字符指针转换到字符数组c里面
A_F_2(c,aa[i].length());
}
return 0;
}
评测
有点长🤭
头文件:
#include <iostream>
#include<iomanip>//setw()
#include <string.h>
using namespace std;
主函数:
①输入n,说明要输入多少个十六进制数
②第一个for循环:
用于输入十六进制数,字符串数组aa的每一个位置用来装每个十六进制数
③第二个for循环用于将一个一个十六进制数单独送到A_F_2()函数中,这个函数自己写的。
④字符串的长度提取的函数为length();
例:string a="abd";
cout<<a.length();
输出为 3
⑤a.c_str()
是将字符串a转换成临时的字符指针char*,临时就是只有这一行有效,下一行a又变回自己的字符串了,不理解可以不用理解,你就知道这样的时候得到a的字符指针就好了。想让它不是临时的可以定义一个字符指针来装它。(不理解的不需要理解)
⑥strcpy();注意dev4.9几版本可能会编译不出来,说你没有定义。dev5.11的可以,应该是版本的原因,放到蓝桥杯里是正确的。其它的编译软件没试过,但是这个确实是对的。需要头文件:#include <string.h>
这个函数就是把后面的字符指针转换成字符数组
我的主函数中strcpy(c,a.c_str());
就是把字符串a转换成字符指针,再转换成字符数组,最后装进字符数组c中。
用strcpy()可以将字符串转换成字符数组;
然后就得到一个十六进制的字符数组c;
int main(int argc, char** argv) {
int n;
cin>>n;//按题目输入有几个十六进制数,自己输入不超过10就好了,还有不小于0,不然输入了又要用户重新输入之类的不符合题目要求
string aa[n]; //这是用来装输入的十六进制数
for(int i=0;i<n;i++){ //输入回车换行,每行输入多多的都可以,输入的时候我们十六进制前面不
// 输入0就没有前导0了,如果输入的十六进制开头有0就不符合题目要求了。
cin>>aa[i];
} //这个for循环已经将所有的十六进制数的字符串装入aa数组中了。
for(int i=0;i<n;i++){ //将每个字符串转成字符数组 才能进行每个字符定位
string a=aa[i]; //再用一个字符串a来装一个十六进制数
char c[aa[i].length()]; //定义字符数组,用于把一个十六进制数 字符串a转换成字符数组c。这个aa[i].length()就是这个字符串的长度,用于创建字符数组大小
//字符串其实就是字符数组,字符数组可以可以一个一个字符进
//行定位,字符串不知道行不行,字符串内的字符我不会。
strcpy(c,a.c_str());//把字符串a转换成字符指针,string转换char* ,然后再将字符指针转换到字符数组c里面
//这个a.c_str()得到的是一个临时的字符指针,然后经过函数转换成字符数组放入字符数组c中。
A_F_2(c,aa[i].length());//把这个字符数组c(输入的一个十六进制数)传入这个函数中,再传入这个十六进制的长度,用于后来创建数组大小用。
}
return 0;
}
函数:void A_F_2(char num[],int n);
char num[]用于接收主函数传进来的字符数组c;
int n 用于定义字符串数组Arry的大小;Arry用于装主函数传进来的这一个十六进制数
①第一个for循环
为了遍历这个十六进制数中的每一位。
i=0就先遍历从左边数第一位数,如果是字符‘1’,
则字符串的数组Arry的第1位赋值为“0001”;
i=1就先遍历从左边数第一位数,如果是字符‘A’,
则字符串的数组Arry的第2位赋值为“1010”(A对应的二进制数);
以此类推......
于是字符串数组Arry内的每一位数都对应了相应的二进制
例:输入 1F
则Arry[0]=“0001”;Arry[1]=“1111”;
②第二个for循环
然后再用字符串拼接把他们变成“00011111”并放入Arrx中
每遍历一位数,就拼接到字符串Arrx后面;
得到一个十六进制转换成 二进制的字符串
再传入下一个函数eight_();中。
void A_F_2(char num[],int n){//把十六进制数转换成二进制数
string Arry[n];
string Arrx;
//int andd=0;
for(int i=0;i<n;i++){
if(num[i]=='0'||num[i]=='1'||num[i]=='2'||num[i]=='3'||num[i]=='4'||num[i]=='5'||num[i]=='6'||num[i]=='7'||num[i]=='8'||num[i]=='9'){
if(num[i]=='0'&&i!=0){
Arry[i]="0000";
}
else if(num[i]=='1'){
Arry[i]="0001";
}
else if(num[i]=='2'){
Arry[i]="0010";
}
else if(num[i]=='3'){
Arry[i]="0011";
}
else if(num[i]=='4'){
Arry[i]="0100";
}
else if(num[i]=='5'){
Arry[i]="0101";
}
else if(num[i]=='6'){
Arry[i]="0110";
}
else if(num[i]=='7'){
Arry[i]="0111";
}
else if(num[i]=='8'){
Arry[i]="1000";
}
else if(num[i]=='9'){
Arry[i]="1001";
}
}
else if (num[i]=='A'||num[i]=='a'){
Arry[i]="1010";
}
else if (num[i]=='B'||num[i]=='b'){
Arry[i]="1011";
}
else if (num[i]=='C'||num[i]=='c'){
Arry[i]="1100";
}
else if (num[i]=='D'||num[i]=='d'){
Arry[i]="1101";
}
else if (num[i]=='E'||num[i]=='e'){
Arry[i]="1110";
}
else if (num[i]=='F'||num[i]=='f'){
Arry[i]="1111";
}
}//还是转换成十六进制字符串
for(int i=0;i<n;i++){//十六进制字符串合并 ,拼接
Arrx+=Arry[i];
}
eight_(Arrx);
}
探讨:
为什么Arry不用字符数组而是用字符串数组?
答:字符串和字符的区别就是字符串能装很多个,字符只能有一个。
字符串相当于字符数组。但是字符数组好定位遍历。
字符串数组的每一位能装一个字符串,而字符数组的每一位只能装一位。
例如 string a[2];
a[0]="123456";
a[1]="a23";
cout<<a[0]<<endl;
cout<<a[1]<<endl;
结果:
123456
a23
例:char a[2]
a[0]='123456';
a[1]='a23';
cout<<a[0]<<endl;
cout<<a[1]<<endl;
结果:
6
3
字符串赋值的要用双引号“”;字符用单引号‘’;
函数:void eight_(string Arrx);
开头将字符串的长度赋值给n用于后面定义数组的大小;还有判断;
void eight_(string Arrx){//二进制字符串转成8进制字符串
int n;
n=Arrx.length();
if(n%3==1){//判断Arrx内字符的个数不能被3整除,余数多出了1位 ,补2个0
Arrx="00"+Arrx;
}
else if(n%3==2){//判断Arrx内字符的个数不能被3整除,余数多出了2位 ,补1个0
Arrx="0"+Arrx;
}
n=Arrx.length();//赋值新的二进制字符串长度
char Arry_eight[n];//我这里直接用Arrx.length()给数组定义大小会出错;
strcpy(Arry_eight,Arrx.c_str());
int i,j;
i=n/3;//8进制位数
j=i-1;//字符数组对应的8进制位数
int x,y,z;
if(Arry_eight[0]=='0'&&Arry_eight[1]=='0'&&Arry_eight[2]=='0'){
j-- ;
i--;
}
char Arrx_eight[i];
x=n-1;
y=n-2;
z=n-3;
for(int o=i;o>0;o--){
if(Arry_eight[z]=='0'&&Arry_eight[y]=='0'&&Arry_eight[x]=='1'){
Arrx_eight[j]='1';
}
else if(Arry_eight[z]=='0'&&Arry_eight[y]=='1'&&Arry_eight[x]=='0'){
Arrx_eight[j]='2';
}
else if(Arry_eight[z]=='0'&&Arry_eight[y]=='1'&&Arry_eight[x]=='1'){
Arrx_eight[j]='3';
}
else if(Arry_eight[z]=='1'&&Arry_eight[y]=='0'&&Arry_eight[x]=='0'){
Arrx_eight[j]='4';
}
else if(Arry_eight[z]=='1'&&Arry_eight[y]=='0'&&Arry_eight[x]=='1'){
Arrx_eight[j]='5';
}
else if(Arry_eight[z]=='1'&&Arry_eight[y]=='1'&&Arry_eight[x]=='0'){
Arrx_eight[j]='6';
}
else if(Arry_eight[z]=='1'&&Arry_eight[y]=='1'&&Arry_eight[x]=='1'){
Arrx_eight[j]='7';
}
else if(Arry_eight[z]=='0'&&Arry_eight[y]=='0'&&Arry_eight[x]=='0' ){
Arrx_eight[j]='0';
}
j--;
x-=3;
y-=3;
z-=3;
}
for(int p=0;p<i;p++){//输出8对应的8进制数
cout<<Arrx_eight[p];
}
cout<<endl;
}
①把这个二进制的字符串,转换成合适转成八进制的二进制字符串;
因为1位十六进制可以转成4位二进制,但是每1位八进制只需要3位二进制;
多出来的以为要放到下一位凑够3位再转八进制;
这个二进制每3个数组成一队,用n%3来判断剩下组不成3个数的二进制有多少位 。(要么多出一位,要么2位嘛,不够3位数)
多出1位数就在整个二进制字符串前边补2个0;多出2位就补1个0;
然后他们就可以组成刚刚好长度可以整除3的字符串;
再把新的二进制字符串长度赋值给n;
②和主函数一样,把这个字符串数组转换成字符数组进行定位;
转换成新的字符数组为Arry_eight;
③看看新的二进制
这里把该二进制能转成多少位八进制的位数赋值给i;j为在数组里对应的位数,j=0则是第一位;
十六进制数转换成二进制数,再转成八进制数,会有一个问题
十六进制 1 ;转成二进制为 0001 ;转换成②的新二进制为000 001,前面3个0没意义;
看看新的二进制开头3位是什么,如果是000那就没意思不用转换成八进制了,i和j的值都减少一位,假装它开头不是000,忽略它;
if(Arry_eight[0]=='0'&&Arry_eight[1]=='0'&&Arry_eight[2]=='0'){
j-- ;
i--;
}
④二进制转成八进制
用Arrx_eight数组来装八进制数;
x,y,z先分别用于定位二进制右边数第一位、第二位、第三位数;
Arry_eight为二进制的字符数组,将他从右边开始进行遍历,每次遍历3位:
如果二进制数右边数第一第二第三为组合为:‘001’,
则让用来装八进制的数组最后一位装‘1’;
如果二进制数右边数第4第5第6为组合为:‘111’(对应八进制为7),
则让用来装八进制的数组倒数第二位装‘7’;
以此类推...... (别忘记二进制中间有000的,③中)
⑤输出八进制数
然后就得到了一个十六进制转八进制的数组;
最后输出到控制台cout;
别忘了输出完后换行
然后就会回到主函数继续传第二个十六进制数到上一个函数,最后又到这个函数输出,以此类推;
⑥疑问
有些同学会疑问,在③中不是有些二进制开头是000吗,最后怎么忽略它了?
那我减小了它转变成八进制的位数,从右边开始转。剩余位数为0了不就停止转换,忽略了吗,对不对。
例子:000 002 001 按理说9位能转3位八进制数,赋值i=3;
我们忽略000,则不要它,能转的就只有001 这2位数,则i就再减1,i就为2;
我循环遍历从最右边的001开始遍历,
遍历第一次一次,把001转成1放进数组最后一位,遍历一次i减少1,i就等于1;
遍历第二次 ,再把002转成2放进数组倒数第二位,i再减少1,此时i等于0,不再进行遍历,000就丢掉啦;
二进制开头如果不是000,则i就不会在在③中判断的时候减少一位
这个肯定不是最优的,读者们可以和我交流交流哈哈哈~~
学会了把字符串转换成字符数组进行定位的话,下面十六进制转十进制之类的就很容易啦;
字符串转字符数组strcpy(), 注意 自己 编译器版本。
c++,蓝桥杯,十六进制字符串转八进制数,字符串转字符数组,
字符数组的定位与遍历
本文章用于记录自己的代码学习与发展。
有帮助到你的,帮我点个赞吧!!!
未经本人允许禁止抄袭说是自己的。