蓝桥杯 基础练习 十六进制转八进制 个人篇c++(包含字符串转字符数组等)

        以下自己写的,代码较长,但是我觉得好理解。会了这个的话,下面几题的十六进制转十进制什么的就很容易了。

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;

结果:

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++,蓝桥杯,十六进制字符串转八进制数,字符串转字符数组,
字符数组的定位与遍历

本文章用于记录自己的代码学习与发展。

有帮助到你的,帮我点个赞吧!!!

未经本人允许禁止抄袭说是自己的。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值