整数的展开
2011-03-14 00:33 Anders Cui 阅读(2866) 评论(2) 编辑 收藏 举报十进制计数
日常生活中整数最常见的表示形式为十进制。如965,它的值是9*10^2+6*10+5。从最开始接触数字,我们就在用十进制计数,可以确信对于任何一个非负整数n,都可以唯一地表示为如下的形式:
(公式1)
其中,k是非负整数,是小于10的非负整数(也即0到9)。可以将这个数字的表示简化为,这也正是我们所习惯的形式,一般把n称为(k+1)位数,如965是一个3位数。虽然根据经验可以得出,任何一个正整数n,都可以唯一地表示为上面的十进制形式,这里还是简单地证明一下(对下面的另外一种展开会有帮助)。
这里的证明需要分为两部分,一是存在性,二是唯一性。
存在性:对于来说,它所能表示的最大数为,如果可以证明它可以表示所有0到范围内的整数,就可以证明存在性了。这里采用归纳法:
基础步骤:k=0时,可以表示0-9(即0到)范围内的所有整数;
归纳步骤:假设对于整数m来说,命题成立,这样可以表示0到范围内的所有整数。考虑整数n,它满足,注意到,所以存在整数(),使得,也就是说可以表示所有0到范围内的整数。
这样,对于任意正整数n,总可以找到一个十进制数来表示,其中k=([]为下取整函数)。
唯一性:可以用反证法证明,这里从略。
n的b进制展开
在计算机系统当中,使用更多的还是二进制、八进制和十六进制。上面十进制表示的结论也可以推广到任意的正整数b(b>1),也就是说,对于任意一个非负整数n,都可以唯一地表示为如下的形式:
(公式2)
这个形式可以称为n以b为基数(base)的展开,或者n的b进制展开,记为。当b=2时,也就是我们非常熟悉的二进制展开了,很多时候会遇到这方面的面试题:如何表示一个整数,二进制展开中有多少个1等等。那现在来考虑给定一个正整数n和基数b(b>1),如何求得n的b进制展开呢?通过公式2可以看到,迭代地使用带余除法,直到商为0即可。
private static readonly string digitTable = "0123456789abcdef";
private static readonly int maxBase = digitTable.Length;
/// <summary>
/// Base b expansion.
/// </summary>
/// <param name="n">n >= 0</param>
/// <param name="b">b in [2, 16]</param>
/// <returns></returns>
public static string Expansion(int n, int b)
{
Stack<string> remainders = new Stack<string>();
do
{
remainders.Push((n % b).ToString());
n /= b;
} while (n > 0);
return string.Join(string.Empty, remainders.ToArray());
}
如果n=165,b=8,则结果为245。
其它的展开形式
有趣的是,在对一个整数进行展开时,除了上面提到的b进制展开,还有其它形式的展开。比如康托尔(Cantor)展开,它是说对于任意一个非负整数n可以唯一地表示为如下的形式:
,其中为整数,且,i=1,2,...,n。
这个看起来有点儿不可思议。对于十进制展开来说,我们可以相信它可以连续地表示所有非负整数,而康托尔展开就没那么明显了。现在再次观察十进制展开,它为何能够连续地表示整数呢?一个k位数能够表示0到范围内的整数,而的下一个整数整数正好是一个(k+1)位数的最小值,这是关键之处。而它能够唯一地表示整数,在于如果i与j不相等,那么一个i位数和一个j位数就不可能相等,这样可以将所有整数按段来分隔了。
下面来考虑康托尔展开是否具有上段提到的两个性质。对于,可以记为,这样仍然可以用一位数、两位数来称呼它们。对于一位数,即k=1时,康托尔展开可以表示的数是0、1;对于两位数,即k=2时,康托尔展开可以表示的数是2、3、4、5;而三位数则可以表示6、7、...、23。看来至少在k不大于3时是可以连续、唯一地表示整数的。一般地,等式成立(可以用数学归纳法证明),而这一等式使得康托尔展开就跟上段提到的十进制展开的两个性质非常类似,这样就可以初步确定康托尔展开可以唯一地表示任意的非负整数了,详细的证明过程与十进制展开的证明类似,不再赘述。
出处:http://anderslly.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。