如何确定一个数字的基数?

时间:2010-04-08 13:20:09

标签: c++ algorithm math numbers

给定一个整数并在某个任意数字系统中重新表示。目的是找到数字系统的基础。例如,数字是10,表示是000010,那么基数应该是10.另一个例子:数字21表示是0010101然后基数是2.还有一个例子是:数字是6,表示os 10100然后base是sqrt(2) 。有谁知道如何解决这个问题?

8 个答案:

答案 0 :(得分:11)

         ___
         \
number = /__ ( digit[i] * base ^ i )

您知道number,您知道所有digit[i],您只需找出base

是否简单或复杂地解决这个等式仍然是一种练习。

答案 1 :(得分:8)

我不认为每个案件都能给出答案。我实际上有理由这样想! =)

给定数字x,在基数b中使用表示a_6 a_5 a_4 a_3 a_2 a_1,找到基数意味着求解

a_6 b^5 + a_5 b^4 + a_4 b^3 + a_3 b^2 + a_2 b^1 + a_1 = x.

这不能一般地完成,如Abel and Ruffini所示。使用较短的数字可能会更幸运,但如果涉及的数字超过四位,则公式会越来越难看。

但是有很多很好的近似算法。请参阅here

答案 2 :(得分:5)

仅对整数来说,并不困难(我们可以枚举)。

让我们看看21及其代表10101

1 * base^4 <= 21 < (1+1) * base^4

让我们为某些基数生成数字:

base   low   high
2      16    32
3      81    162

更一般地说,我们将N表示为Σa i * base i 。考虑I I 非空的最大功率,我们有:

a[I] * base^I <= N < (a[I] + 1) * base^I  # does not matter if not representable

# Isolate base term
N / (a[I] + 1) < base^I <= N / a[I]

# Ith root
Ithroot( N / (a[I] + 1) ) < base <= Ithroot( N / a[I] )

# Or as a range
base in ] Ithroot(N / (a[I] + 1)), Ithroot( N / a[I] ) ]

在整数基数的情况下,或者如果你有一个已知可能基数的列表,我怀疑他们会有很多可能性,所以我们可以尝试一下。

请注意,实际获取Ithroot的{​​{1}}并从此处迭代而不是计算第二个(应该足够接近)可能会更快...但我需要数学回顾那种直觉。

如果你真的没有任何想法(试图找到一个浮动基地)...我猜这有点困难,但你可以随后改进不等式(包括一个或两个以上的术语)属性。

答案 3 :(得分:3)

这样的算法应该找到一个整数的基数,并且应该至少缩小非整数基数的选择:

  • N成为你的整数,R成为神秘基地的代表。
  • 找到R中的最大数字,并将其命名为r
    • 您知道您的基数至少为r + 1
  • 对于base == (r+1, r+2, ...),让I代表基座R中解释的base
    • 如果I等于N,那么base就是您的神秘基础。
    • 如果I小于N,请尝试下一个基地。
    • 如果I大于N,那么您的基数介于base - 1base之间。

这是一种蛮力方法,但应该有效。如果base明显小于I,您也可以通过将N增加多个来加快速度。

其他可能有助于加快速度的事情,特别是在非整数基数的情况下:请记住,正如几个人所提到的,任意基数中的数字可以扩展为多项式,如

x = a[n]*base^n + a[n-1]*base^(n-1) + ... + a[2]*base^2 + a[1]*base + a[0]

在评估潜在基数时,您无需转换整个数字。首先只转换最大的术语a[n]*base^n。如果这大于x,那么您已经知道您的基数太大了。否则,一次添加一个术语(从最重要到最不重要)。这样,在您知道基础错误之后,您不会浪费时间计算术语。

此外,还有另一种消除潜在基础的快捷方法。请注意,您可以重新排列上面的多项式表达式并获取

(x - a[0]) = a[n]*base^n + a[n-1]*base^(n-1) + ... + a[2]*base^2 + a[1]*base

(x - a[0]) = (a[n]*base^(n-1) + a[n-1]*base^(n-2) + ... + a[2]*base + a[1])*base

您知道xa[0]的值(“1”数字,无论基数如何,您都可以解释它)。这为您提供了(x - a[0])必须被base整除的额外条件(因为您的所有a[]值都是整数)。如果您计算(x - a[0]) % base并获得非零结果,那么base就不能成为正确的基础。

答案 4 :(得分:1)

我不确定这是否可以有效解决。我只想尝试选择一个随机基数,看看给定基数是否结果更小,更大或等于数字。如果它较小,请选择较大的底座,以防较大的底座选择较小的底座,否则你就有了正确的底座。

答案 5 :(得分:1)

这应该给你一个起点:

从数字和表示创建一个等式,数字42和代表“0010203”变为:

1 * base ^ 4 + 2 * base ^ 2 + 3 = 42

现在解决方程式以获得base的值。

答案 6 :(得分:1)

我想你需要尝试并检查不同的基础。为了提高效率,您的起始基数可能是max(digit)+ 1,因为您知道它不会小于此值。如果这个太小,直到你超过,然后使用二进制搜索缩小它。这样,对于正常情况,您的算法应该在O(log n)中运行。

答案 7 :(得分:1)

其他一些帖子表明,可以通过找到数字所代表的多项式的根来找到解。当然,这些通常是有效的,尽管它们会产生负面和复杂的基础以及正整数。

另一种方法是将其转换为整数规划问题,并使用分支绑定解决。

但我怀疑猜测和测试的建议会比任何更聪明的建议更快。