针对做题的进制转换问题的一些解决方案
注意:这篇文章略长,各种情况都想要讲一下,如果想要直接看建议的方法,希望可以跳过以下这些,直接看最后的总结部分。
1.itoa 函数
itoa()是广泛应用的非标准C语言和C++语言扩展函数。由于它不是标准C/C++语言函数,所以不能在所有的编译器中使用。但是,大多数的编译器(如Windows上的)通常在
<stdlib.h>/<cstdlib>
头文件中包含这个函数。
//函数原型
char *itoa(int value, char *str, int radix)
value 是被转换的整数
str 转换后存储的字符数组
radix 转换进制数,可以是 2, 8, 10, 16 等等
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
char str[25];
memset(str, 0, sizeof(str));
itoa(98, str, 2);
printf("10--2进制: %s\n", str);
memset(str, 0, sizeof(str));
itoa(98, str, 8);
printf("10--8进制: %s\n", str);
memset(str, 0, sizeof(str));
itoa(98, str, 16);
printf("10--16进制: %s\n", str);
memset(str, 0, sizeof(str));
itoa(076, str, 2);
printf("8--2进制: %s\n", str);
memset(str, 0, sizeof(str));
itoa(076, str, 10);
printf("8--10进制: %s\n", str);
memset(str, 0, sizeof(str));
itoa(076, str, 16);
printf("8--16进制: %s\n", str);
memset(str, 0, sizeof(str));
itoa(0xffff, str, 2);
printf("16--2进制: %s\n", str);
memset(str, 0, sizeof(str));
itoa(0xffff, str, 8);
printf("16--8进制: %s\n", str);
memset(str, 0, sizeof(str));
itoa(0xffff, str, 10);
printf("16--10进制: %s\n", str);
return 0;
}
由上可知,itoa()可以实现10到2、8、16的转换,8到2、10、16的转换,16到2、8、10的转换,唯独没有2进制到其他进制的转换。
功能比较强大,但是——他是一个非标准函数,在PAT运行环境下进行测试,显示编译失败,所以暂时不要考虑这个。
2.sprintf 函数
把格式化数据写入某个字符缓冲区中,头文件为<stdio.h>/<cstdio>
//函数原型
int sprintf(char *buffer, const char *format, [argument]...)
buffer: char*型数组,指向将要写入的字符串的缓冲区
format: 格式化字符串
[argument]...: 可选参数,就是任何类型的数据
sprintf可完成8,10,16进制间的互相转换。
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main(){
char str[25];
memset(str, 0, sizeof(str));
sprintf(str, "%o", 1024);
printf("8进制: %s\n", str);
memset(str, 0, sizeof(str));
sprintf(str, "%x", 1024);
printf("16进制: %s\n", str);
return 0;
}
另外需要注意的地方就是,sprintf()函数还有很方便的截取功能,具体可以自行搜索或者查看并学习《算法笔记》P53.
3.现在推荐一种自己想到搭配出的一种方法:
功能:适用于将一个数A的2进制(包括可以限制输出位数)、8进制、10进制、16进制的数据格式保存到一个string类型变量str中。string类型在c++做题中用的还是很多,也很方便的,所以我认为还可以。
#include <iostream>
#include <algorithm>
#include <queue>
#include <vector>
#include <map>
#include <stack>
#include <string>
#include <bitset>
#include <sstream>
using namespace std;
stringstream ss;
int main()
{
int a=1244;
string str;
//将数的16进制格式形式保存到string类型变量中
// ss<<std::hex<<a;
// ss>>str;
//
// cout<<str<<endl;
//将数的8进制格式形式保存到string类型变量中
// ss<<std::hex<<a;
// ss>>str;
//
// cout<<str<<endl;
//将数的2进制格式形式保存到string类型变量中
ss<<std::bitset<10>(a);
ss>>str;
cout<<str<<endl;
return 0;
}
这里关键就是用到了头文件:
#include <sstream>
#include <bitset>
这些比较陌生的头文件。
使用sstream中的stringstream,定义了ss,可以结合std域中的
std::hex(16进制)、std::dec(10进制)、std::oct(8进制)、std::bitset<?>(num)
——这里?位置代表输出格式数据为多少位,num为对应的要转换为2进制的数。
以上搭配起来形成“流”时,就实现了将一个数A的对应的常用的2进制、8进制、10进制、16进制格式保存到了string类型变量str中了。
这里需要注意的一点就是,流变量stringstream ss 是一次性的,这一点很重要,不可以重复多次使用。
4.以上都是针对常见的2/8/10/16进制的转换,那么针对任意进制之间的转换呢?
我建议大家查看《算法笔记》进制转换章节P93。
总结
针对以上内容,我的总结就是对于做题当中的进制转换部分:
1.如果是常规的2/8/10/16进制的转换,可以采用第3点中stringstream搭配std::hex等的流方法保存到string类型变量中进行操作;
2.如果是题意已经表明了需要实现任意进制转换功能的话,可以记下《算法笔记》P93中的关于进制转换的代码。
以上均属于个人建议,大家还可以直接采用总结中的第2种方法,进制转换题一来,就把模板代码贴上去,虽然麻烦点,但是通用;我推荐的总结中的第一种方法是针对我的编程习惯和对于string类型的使用上的喜爱得出的,希望大家可以根据实际情况自行决定。