我对数字及其表示有问题。
我有一组自然数,最大可能值为1 000 000,称之为NUM。从集合NUM中取1-50个数字,其中可以多次包含相同的数字,将其称为IN。使用以下条件将IN设置转换为单个数字(OUT):
OUT将唯一标识设置IN。
可以使用两个OUT编号(<,>,< =,> =)的比较,完全取决于创建OUT的时间(一次只创建一个OUT) )
(3。优选)可以将OUT转换为原始集IN。
示例:
NUM={1,2,3,4,5,6,7,8,9,10,......,1000000}
IN1={2,4,6}, creation time 1
IN2={1,3,8}, creation time 2
IN3={4,4,4}, creation time 3
OUT1=function(IN1,time 1)
OUT2=function(IN2,time 2)
OUT3=function(IN3,time 3)
OUT1!= OUT2!= OUT3
OUT1< OUT2< OUT3
IN1 = reverse_function(OUT1)
有没有办法找到这个function()
或reverse_function()
???
答案 0 :(得分:4)
有几种方法。 一种非常常见的方法是将每个不同的数字映射到素数,然后编码这个数字在指数中出现的频率。
它被称为Gödel numbering
如果每个数字只能出现一次,你甚至可以摆脱从数字到素数的映射。比你可以将数字本身存储在素数的指数中(每个数字的不同素数) 例如你想存储{123,47,2}你能做到吗? 像这样:result=(2^123)*(3^47)*(5^2)
你可以通过进行素数分解并查看指数来反转这一点。
答案 1 :(得分:2)
如果IN是一组包含1-50个成员的数字,其中每个成员可以是1到1,000,000之间的数字,那么你基本上不能执行OUT唯一标识IN的部分。允许重复。
显然,如果集合只包含一个数字,那么只有一百万个可能的集合,因此你的函数只需返回一百万个可能的值。
如果集合总是包含两个数字,并且它们可能是相同的数字,则可能有500,000,500,000(5000亿)种组合,因此您的函数需要返回5000亿个可能的值。
如果集合包含一个或两个值,那么显然有5000亿+ 100万个可能的返回值。
如果我们添加具有三个数字的集合,则可能的返回值将移动到四元组中。当我们包含具有二十个数字的集合时,唯一地标识每个集合所需的值的范围已经达到40个googols(在其之后具有101个零的4个)。这个值需要超过42个字节才能存储在内存中(我怀疑你使用的是一种允许340位整数的语言)。
这不是一个可行的想法。使用管道字符或类似字符加入数字的文本表示会更好。虽然仍有尽可能多的可能值,但您不会分配足够的空间来存储每一个 - 只是您使用的那些。
" 1 | 2 | 3"唯一标识集合{1,2,3},可逆,可清除,也是人类可读的。它还占用了6个字节的内存,并且构建时间非常短。任何生成唯一的340位整数来表示所有可能值的算法都将变得复杂,笨拙并生成您无法执行任何操作的值。