博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
将一个长度最多为30位数字的十进制非负整数转换为二进制数输出 c语言 大数处理
阅读量:2430 次
发布时间:2019-05-10

本文共 3528 字,大约阅读时间需要 11 分钟。

Time Limit: 1000 ms

Memory Limit: 32768 mb

将一个长度最多为30位数字的十进制非负整数转换为二进制数输出

输入描述:

多组数据,每行为一个长度不超过30位的十进制非负整数。(注意是10进制数字的个数可能有30个,而非30bits的整数)

输出描述:

每行输出对应的二进制数。

输入样例#:

0138

输出样例#:

01111000

分析:考察点是进制转换,难点是涉及到大数。

int类型在C语言中占4个字节,即32个二进制位。当表示正数时,最高位为符号位(符号位为0),最大的正数是 0111 1111 1111 1111 1111 1111 1111 1111 即2^31 -1 = 2147483647。当表示负数时,最高位为符号位(符号位为1),最小的负数是 1000 0000 0000 0000 0000 0000 0000 0000 而在计算机中是以补码的形式存储的,C语言规定 1000 0000 0000 0000 0000 0000 0000 0000 的补码为-2147483648。所以C语言中int的取值范围为:-2147483648~2147483647

但是本题中有30位长度,明显超过了int型变量的范围,因此可以尝试一下以下思路。

思路:

进制转换的精髓就在于除n取余,那么可以运用手动除法运算的方法,具体如下:

//以输入十进制123转换为2进制为例//声明,result数组用于存放每一轮运算所得的余数,k用于存放每一次运算所得的余数,当此次运算为本轮运算的最后一位,就将k存入result数组。注意区分每一轮与每一次运算的区别//第一趟:这里一位一位的运算,先从百位运算,然后运算十位,然后运算个位,与手动运算除法的顺序一致。//第一轮运算输入123//百位运算1/2=0				//百位置0,说明这一轮运算百位就可以结束了,不需要第二轮1%2=1。     //由于余数是1,所以有余数需要传给下一位,本例中也就是十位k=1.       //将k置为1,意味着在下一次运算中要给下一次运算中加上此次运算多出来的数//十位运算,由于百位上有余数1,因此十位上的2运算不能按照2运算,而是按照1x10+2=12运算12/2=6		//这次运算的结果是6,说明十位上是6,不是0,所以这趟运算还不能结束,说明十位上的运算还需要第二轮,第三轮,甚至更多,直至十位上的数位0才算这趟运算结束12%2=0		//此次运算可以整除,因此将k置为0k=0				//个位运算第一次,由于十位上的余数是0,因此个位的运算按照原本的数进行运算3/2=13%2=1k=1				//第一轮运算结束,将k的值也就是1存入result数组中,此时result数组的值为1//第二趟//第二趟第一轮运算:输入的是61//十位运算6/2=36%2=0k=0//个位运算1/2=01%2=1k=1。    //本轮结束,将k=1存入result,此时result为11//第二趟第二轮,输入的是:30//十位运算3/2=13%2=1k=1//k=1,因此各位运算的时候要将此余数纳入考虑范围//个位运算,上一位运算的余数乘10加上本位上的数1x10+0=1010/2=510%2=0k=0。   //本轮运算结束,将k=0存入result数组,此时result为110//第二趟第三轮,输入的是:15//十位运算1/2=0		//注意十位上的数除之后剩0了,意味着本趟运算结束1%2=1k=1//个位运算,所以看到这里了,此次运算的数是多少呢15/2=715%2=1k=1。  //本轮运算结束,将开存入result,此时result为1101//第三趟//第三趟第一轮。输入7//个位运算,其实也就剩个位了7/2=37%2=1k=1//将k存入result,即result为11011//第三趟第二轮,输入33/2=13%2=1k=1//将k存入result,即result为110111//第三趟第三轮,输入11/2=0 //个位除之后为0,本趟结束1%2=1k=1//将k存入result,即result为1101111//最后将result:1101111逆序输出为1111011,也就是123转换为2进制是1111011

代码如下:

#include
#include
void conservatemton(int m,char *s,int n){
int len=strlen(s); int k,lastn=0; //变量k用于存放每次运算所得的余数。lastn用于标记result数组的长度,放便后续的一系列操作。 char result[32]={
'0'}; //result数组是用来存放每一趟进制除n之后得到的余数,将数组逆序输出就是进制转换需要的结果,本行代码是将数组初始化。 for (int i = 0; i < len; ) {
k=0; for (int j = i; j < len; ++j) //除n取余,进制转换累问题的核心。 {
int t=(k*m+s[j]-'0')%n; s[j]=(k*m+s[j]-'0')/n+'0'; k=t; } lastn++; result[lastn]=((char)(k+'0')); while(s[i]=='0')i++; //当s[i]位置上的字符是0时,才标志一趟运算的结束。 } for (int k = strlen(result); k >0; k--) {
printf("%c",result[k]); } printf("\n");}int main(int argc, char const *argv[]){
char a[100]; while(~scanf("%s",a)){
conservatemton(10,a,2); } return 0;}

这里在自己电脑可以运行,但是在oj上提示runtime error,这里是因为在函数内部每一次都开辟一个result数组,导致报此类错误,于是进行了改进,设置result数组为公共变量,这就避免了报错,但是注意同时要增加对于result数组的初始化工作。

#include
#include
char result[32]; //定义一个全局变量,为了避免了在运行过程功函数多次开辟同样空间,节省空间,也避免了栈溢出。 //result数组是用来存放每一趟进制除n之后得到的余数,将数组逆序输出就是进制转换需要的结果。void conservatemton(int m,char *s,int n){
int len=strlen(s); int k,lastn=0; //变量k用于存放每次运算所得的余数。lastn用于标记result数组的长度,放便后续的一系列操作。 for (int i = 0; i <32; ++i) //这一步是对将result数组置为空,也就是初始化,防止前面一趟的数据对后面一趟的数据产生干扰。 {
result[i]='\0'; } for (int i = 0; i < len;) {
k=0; for (int j = i; j < len; ++j) //除n取余,进制转换问题的核心 {
int t=(k*m+s[j]-'0')%n; s[j]=(k*m+s[j]-'0')/n+'0'; k=t; } result[lastn++]=((char)k+'0'); while(s[i]=='0')i++; //当s[i]位置上的字符是0时,才标志一趟运算的结束 } for (int k = lastn-1; k >=0; --k) {
printf("%c",result[k]); } printf("\n");}int main(int argc, char const *argv[]){
char a[32]; while(~scanf("%s",a)){
conservatemton(10,a,2); } return 0;}

这样就可以ac了。

转载地址:http://nitmb.baihongyu.com/

你可能感兴趣的文章
【Java】【Web】JavaWeb相关知识总结 2018-9-17
查看>>
【数据库】突破单一数据库的性能限制——数据库-分库分表总结 2018-9-20
查看>>
Slurm——作业调度处理
查看>>
Lustre 维护
查看>>
Lustre—磁盘配额测试
查看>>
SSH加密密码中的非对称式密码学
查看>>
Mac Redis安装入门教程
查看>>
python3安装教程配置配置阿里云
查看>>
Mac快捷键和实用技巧
查看>>
Git的多人协作和分支处理测试
查看>>
mysql索引回表
查看>>
iterm2 保存阿里云登陆并防止断开连接
查看>>
brew安装
查看>>
mysql5.7初始密码查看及密码重置
查看>>
go语言实现2048小游戏(完整代码)
查看>>
动态二维码免费制作
查看>>
C语言贪吃蛇
查看>>
Python练手项目
查看>>
知网毕业论文爬取
查看>>
Django无法显示图片
查看>>