题目描述
输入一个十进制数N,将它转换成R进制数输出。
输入
输入数据包含多个测试实例,每个测试实例包含两个整数N(32位整数)和R(2<=R<=16)。
输出
为每个测试实例输出转换后的数,每个输出占一行。如果R大于10,则对应的数字规则参考16进制(比如,10用A表示,等等)。
样例输入
7 2 23 12 -4 3样例输出
111 1B -11
主要思路是求余运算,将这个十进制数与进制数求余,例如将23转为12进制,则是23 % 12。在数学上我们做进制转换是通过短除法不断求得余数,然后将得到的所有余数倒序,来解决这个问题的,但是这个题目需要考虑更多的东西,一个是超过10的进制需要用大写字母代替,例如16进制里的ABCDEF,这是题目明示的,还有从样例里我们也可以看到负数的转换,在写代码的时候需要处理一下。
我们理一下写程序的思路,首先我们使用C++ STL的栈来解决倒序问题,将一个个的余数入栈,最后取出,就可以得到倒序的数组。由于输出中可能带有字母,我们用string对象来输出结果。我先把代码贴上来:
#include <cstdio>
#include <algorithm>
#include <string>
#include <iostream>
#include <stack>
#include <sstream>
using namespace std;
string trans(int a,int r){
stack<char> s;
string res;
//A:
if(a < 0){
a = abs(a);
res += '-';
}
//B:
if(a < r){
stringstream s;
s << a;
res += s.str();
return res;
}
while(a){
//cout << a % r << endl;
if(a % r >= 10){
//C:
s.push(a % r - 10 + 'A');
}
else{
s.push(a % r + 48);
}
a /= r;
}
while(!s.empty()){
res += s.top();
s.pop();
}
return res;
}
int main(){
int n,r;
while(scanf("%d%d",&n,&r) != EOF){
cout << trans(n,r) << endl;
}
return 0;
}
代码里我用注释标注了A B C,便于我讲解。首先我写了一个trans函数来处理进制转换,a是要转换的数,r是进制数。在A处我处理负数的情况,就是将要返回的字符串res里先加入一个负号,然后将数字做绝对值,在接下来的代码里按正数处理。在B处我处理传进来的数不需要转换的情况,例如输入一个8让我们转成12进制,这个时候直接返回8就行,这里使用了stringstream来把int转成string(C++如此麻烦)。然后是C处,C所处的整个循环用于处理余数并入栈,我分了两种情况,一是余数大于10,需要添加字母的情况,二是余数小于10,不需要添加字母的情况,至于-10 ,+48,这些操作,是为了将数字转为char(ascii)以便后面加入到字符串里。在trans()函数的最后,遍历栈s,取出字符并拼接到res里,返回res。代码已在OJ上AC。