我有一个非常大的正整数(百万位)。我需要用尽可能小的函数来表示它,这个数字是可变的,这意味着,我需要一个生成最小函数的算法来获得给定的数字。
示例:对于数字29512665430652752148753480226197736314359272517043832886063884637676943433478020332709411004889,算法必须返回“9 ^ 99”。它必须能够分析数字并始终返回表示数字的数学函数。示例编号21847450052839212624230656502990235142567050104912751880812823948662932355202必须返回“9 ^ 5 ^ 16 + 1”。
答案 0 :(得分:12)
回答你的问题:除非你限制自己使用一些特定的功能,否则这是不可能的。
编辑:即使在您的示例中,您如何知道21 847 450 052 839 212 624 230 656 502 990 235的最短表示142 567 050 104 912 751 880 812 823 948 662 932 355 202实际上是9 ^ 5 ^ 16 + 1?即使在特定案例中,证明也不是很难吗?
如果您将自己局限于某些功能集,则可以使用以下算法:
For i = 1 to n
enumerate all strings s of length i
if s represents a valid expression according to rules chosen a priori,
and evaluates to the number in the input,
return s
保证停止,因为在外循环的最后一次迭代(i = n)中,你最终会得到一个包含输入的字符串。
当然,这不是很有效率。特别是O(b n )其中n是输入的长度,b是字母表的大小。
答案 1 :(得分:5)
扩展@ ybungalobill的简洁回答,你的函数等价于计算任意字符串的Kolmogorov复杂度的函数。 (如果将非常大的数字的每个数字视为字符,将数字视为字符序列,则等效性很明显。)
根据关于Kolmogorov复杂性的维基百科页面,给出字符串K(s)
复杂性的s
函数是not a computable function。 (该页面包含证明。)
换句话说,您想要的算法根本不存在。
答案 2 :(得分:0)
@BlueRaja - Danny Pflughoeft:是的,确实如此。我正在尝试创建一些使用此算法的压缩,但顺便说一下这是不可能的。
这是因为在技术上不可能压缩任意数据,出于同样的原因,但这并不能阻止我们这样做:)
然而,还有更好的压缩数据的方法。例如,看一下LZ。它无处不在,你几乎可以找到一个库来为你做压缩,无论你写的是什么语言。DEFLATE是另一种流行的语言。
希望有所帮助!
答案 3 :(得分:0)
如果你不是在寻找最佳性,只是一个相当不错的工作,那么你可以使用一些启发式方法。例如,尝试使用以下所有
分解nn = a^k + b
代表k = 2, 3, ..., log n
,并选择具有最小a + b
的那个。您可以使用a
和b
计算a = floor(n^(1/k))
和b = n-a^k
。然后递归a
和b
。
当然,这只使用取幂和加法来找到一个好的压缩。如果您也允许减法,请改用a=round(n^(1/k))
,让b
为负数。
允许乘法也会让它变得更加困难,因为你可能需要考虑因素n
。