Processing math: 3%
NOIP学习小站
西安交通大学附属中学航天学校

数组例题——进制转换

以我们熟悉的十进制数为例,十进制数只有0、1、2、3、4、5、6、7、8、9这10个基本数字(也称为数码)。同样的,二进制数只有0、1两个数码,八进制数只有0、1、2、3、4、5、6、7这八个数码。

对于 n 进制数 m,书写时如果某位上数字超过10,为了避免混淆,用大写字母来表示这个位上的数。A表示10、B表示11、C表示12,...,以此类推。那么十六进制数有0、1、2、3、4、5、6、7、8、9、A、B、C、D、E、F这16个数码。

一、十进制数转其他进制

十进制数转换成其他进制可以使用短除法:

↑ 十进制数53转二进制 ↑
↑ 十进制数51994转十六进制 ↑

输入m,n0 \le m \le 1,000,000,2 \le n \le 16),输出十进制数mn进制的结果。

分析:十进制数mn进制,依据短除法,m每次除以n,写下余数,将商重新赋值给m,一直重复上面的操作直到m为0。将所余数反向书写就是结果。可以将余数依次存入到数组中,最后逆序输出即可。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
#include<iostream>
using namespace std;
//char数组s用于输出短除法的余数对应的数码
//如果余数为0,那么对应的数码是s[0]——'0';
//如果余数为10,那么对应的数码是s[10]——'A'
//如果余数为i,那么对应的数码是s[i]
char s[16] = {
'0','1','2','3','4',
'5','6','7','8','9',
'A','B','C','D','E','F'
};
//数组r记录所有余数
int r[1000];
int main()
{
int m,n,cnt = 0;
cin>>m>>n;
while(m){ //while(m!=0){的简写
r[cnt++] = m%n;
m /= n;
}
if(cnt==0) r[cnt++] = 0; //m为0特殊处理
for(int i=cnt-1;i>=0;i--){
cout<<s[r[i]]; //注意这里的经典写法
/*如果不理解上面的写法,可以看下面和上一句等效但简单一些的拆解写法
int p = r[i]; //p是一个余数
cout<<s[p]; //输出p在s数组中对应的数码
*/
}
return 0;
}
#include<iostream> using namespace std; //char数组s用于输出短除法的余数对应的数码 //如果余数为0,那么对应的数码是s[0]——'0'; //如果余数为10,那么对应的数码是s[10]——'A' //如果余数为i,那么对应的数码是s[i] char s[16] = { '0','1','2','3','4', '5','6','7','8','9', 'A','B','C','D','E','F' }; //数组r记录所有余数 int r[1000]; int main() { int m,n,cnt = 0; cin>>m>>n; while(m){ //while(m!=0){的简写 r[cnt++] = m%n; m /= n; } if(cnt==0) r[cnt++] = 0; //m为0特殊处理 for(int i=cnt-1;i>=0;i--){ cout<<s[r[i]]; //注意这里的经典写法 /*如果不理解上面的写法,可以看下面和上一句等效但简单一些的拆解写法 int p = r[i]; //p是一个余数 cout<<s[p]; //输出p在s数组中对应的数码 */ } return 0; }
#include<iostream>
using namespace std;
//char数组s用于输出短除法的余数对应的数码
//如果余数为0,那么对应的数码是s[0]——'0';
//如果余数为10,那么对应的数码是s[10]——'A' 
//如果余数为i,那么对应的数码是s[i]
char s[16] = {
	'0','1','2','3','4',
	'5','6','7','8','9',
	'A','B','C','D','E','F'
};
//数组r记录所有余数 
int r[1000];
int main()
{
    int m,n,cnt = 0;
    cin>>m>>n;
    
    while(m){       //while(m!=0){的简写
    	r[cnt++] = m%n;
    	m /= n;
	}
	
	if(cnt==0) r[cnt++] = 0;   //m为0特殊处理
	 
	for(int i=cnt-1;i>=0;i--){
		cout<<s[r[i]];    //注意这里的经典写法
		/*如果不理解上面的写法,可以看下面和上一句等效但简单一些的拆解写法
				int p = r[i];     //p是一个余数
				cout<<s[p]; 	  //输出p在s数组中对应的数码
				*/	 
	}
    return 0; 
}

二、其他进制数转十进制

可以使用“按权展开求和”将 n 进制数转换成十进制数:

例如二进制数10101,其实是:1 \times 2^4 + 0 \times 2^3+1 \times 2^2+0 \times 2^1+1 \times 2^0 = 21;

又例如八进制数127,其实是:1 \times 8^2 + 2 \times 8^1 + 7 \times 8^0 = 87;

又例如十六进制数A1F,其实就是:10 \times 16^2 + 1 \times 16^1 + 15 \times 16^0 = 2591;

甚至对于十进制数12365,其实就是:1 \times 10^4 +2 \times 10^3 +3 \times 10^2 + 6 \times 10^1 + 5 \times 10^0 = 12365。

问题:输入正整数 n2 \le n \le 16),以及n进制数K,输出其十进制数m。例如输入 16 FF,那么应该输出255。

解法一:将n进制数K按照字符的形式输入,每位是一个字符,存入到char数组中,使用按权展开求和的方法计算对应的十进制数(需要注意的是权值的处理):

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
#include<iostream>
using namespace std;
char num[1010];
int main()
{
int n,cnt = 0;
char one;
cin>>n;
//将n进制数每位当作字符存入字符数组
while(cin>>one){
num[cnt++] = one;
}
long long m = 0,p = 1;
//按权展开求和(低位 → 高位依次处理)
for(int i=cnt-1;i>=0;i--){
if(num[i]>='0' && num[i]<='9'){
m += p*(num[i]-'0');
}else if(num[i]>='A' && num[i]<='F'){
m += p*(10+num[i]-'A');
}
//处理权值p
p *= n;
}
cout<<m;
return 0;
}
#include<iostream> using namespace std; char num[1010]; int main() { int n,cnt = 0; char one; cin>>n; //将n进制数每位当作字符存入字符数组 while(cin>>one){ num[cnt++] = one; } long long m = 0,p = 1; //按权展开求和(低位 → 高位依次处理) for(int i=cnt-1;i>=0;i--){ if(num[i]>='0' && num[i]<='9'){ m += p*(num[i]-'0'); }else if(num[i]>='A' && num[i]<='F'){ m += p*(10+num[i]-'A'); } //处理权值p p *= n; } cout<<m; return 0; }
#include<iostream>
using namespace std;
char num[1010];
int main()
{
    int n,cnt = 0;
    char one;
    cin>>n;
    
    //将n进制数每位当作字符存入字符数组 
    while(cin>>one){
        num[cnt++] = one;
    }
    
    long long m = 0,p = 1;
    //按权展开求和(低位 → 高位依次处理) 
    for(int i=cnt-1;i>=0;i--){
    	if(num[i]>='0' && num[i]<='9'){
    		m += p*(num[i]-'0');
		}else if(num[i]>='A' && num[i]<='F'){
    		m += p*(10+num[i]-'A');
		}
		//处理权值p 
		p *= n;
	}
	
    cout<<m;
    return 0; 
}

解法二:可以使用while(cin>>char)的方式输入n进制数K的每一位(当作字符输入),一边输入,一边组装十进制数m

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
#include<iostream>
using namespace std;
int main()
{
int n;
long long m = 0;
char one;
cin>>n;
while(cin>>one){
m = m*n; //m放大n倍
if(one>='0' && one<='9'){ //输入的是'0'~'9'中的某个字符
m += one - '0'; //one-'0'就是该位数字
}else if(one>='A' && one<='F'){ //输入的是'A'~'F'中的某个字符
m += 10 + one - 'A'; //10+one-'A'就是该位数字
}
}
cout<<m;
return 0;
}
#include<iostream> using namespace std; int main() { int n; long long m = 0; char one; cin>>n; while(cin>>one){ m = m*n; //m放大n倍 if(one>='0' && one<='9'){ //输入的是'0'~'9'中的某个字符 m += one - '0'; //one-'0'就是该位数字 }else if(one>='A' && one<='F'){ //输入的是'A'~'F'中的某个字符 m += 10 + one - 'A'; //10+one-'A'就是该位数字 } } cout<<m; return 0; }
#include<iostream>
using namespace std;
int main()
{
    int n;
    long long m = 0;
	char one;
	cin>>n;
	while(cin>>one){
		m = m*n;     //m放大n倍
		if(one>='0' && one<='9'){        //输入的是'0'~'9'中的某个字符
			m += one - '0';              //one-'0'就是该位数字
		}else if(one>='A' && one<='F'){  //输入的是'A'~'F'中的某个字符
			m += 10 + one - 'A';         //10+one-'A'就是该位数字
		}
	}
	cout<<m;
    return 0; 
}

登录

注册