> 文章列表 > 【十分钟学会一个算法】进制转换

【十分钟学会一个算法】进制转换

【十分钟学会一个算法】进制转换

学习不止于求知识,更是为人处世的修养,勤于思考,不怕困难,方能成就一番大事业。

文章目录

题目

给定一个十进制数,转换为k进制。

解析

作为平时最常接触的,我们先看2进制的转换。例如,将163转换为2进制数。

  1. 用163/2=81…1,余数是1.
  2. 用上一次的结果81/2=40…1,余数是1.
  3. 依次类推,最后得到余数从左到右分别是1,1,0,0,0,1,0,1.
  4. 由于除的次数越多,余数的权重越大,因此需要逆序输出,也就是10100011.

不难看出,这是一个迭代的过程。我们写出这个过程的第1版代码:

void DC_v1(int b,int k)//第1版进制转换
{for (int i = 0; i < 100; i++) {a[i] = -1;}int i = 0;while (b){a[i] = b % k;b /= k;i++;}int j = 99;while (a[j] == -1) {j--;}while (j >= 0) {printf("%d", a[j]);j--;}
}

但在实际题目中,一般都会要求你给出某负进制的转换。为了理解这个过程,我们给出一个例子,来表示我们直观上会如何去做。

题目:将21转换成-4进制

  1. 21/-4=-5…1,余数为1
  2. -5/-4=1…-1,余数为。。。-1?

-1显然不是我们要的结果,在写结果的时候不可能有某一位是负数。问题出在哪里呢?
事实上,余数运算从来没有定义过除数或被除数是负数的情况,因此上面的直觉推理整个都是错误的。
因此,我们需要定义一种新的类似取余的运算。我们定义余数=被除数-比被除数小的除数的最大倍数。因此,上面题目的解法应该是:

  1. 21/-4=-5…1,余数为1
  2. 计算-5/-4时,我们向下找,发现小于-5且是-4倍数的最大数是-8(类似于高斯函数,应该好理解),-5-(-8)=3,因此正确的过程是:-5/-4=2…3,余数为3.
  3. 依次类推,2/-4=0…2,注意-4的0倍是0
  4. 因此,21的-4进制就是231.

因此,我们可以写出第2版代码,其中k可以为负数:

void DC_v2(int b,int k)//第2版进制转换
{for (int i = 0; i < 100; i++) {a[i] = -1;}int i = 0;if (k > 0 && b > 0) {while (b) {a[i] = b % k;b /= k;i++;}}else {int j = 0;while (b) {if (b % k != 0) {b--;j++;}if(b%k==0) {b /= k;a[i] = j;j = 0;i++;}}}int j = 99;while (a[j] == -1) {j--;}while (j >= 0) {printf("%d", a[j]);j--;}
}

进制转换的知识点到这里就结束啦,我是霜_哀,在算法之路上努力前行的一位萌新,感谢你的阅读!如果觉得好的话,可以关注一下,我会在将来带来更多更全面的算法讲解!