我想将一系列数字转换为一个单独的数字,该数字保留各个值以及它们的位置。例如,提供以下序列-
1,6,7,8,9,45,67
例如,如果应用简单的加法即 1+6+7+8+9+45+67,则会生成一个数字。但是从这个数字中,我们无法按其顺序提取每个单独的数字 [即 1,6,7,8,9,...]。
是否有任何方法可以在没有任何歧义的情况下实现此功能[即仅从数字中提取1个唯一的数字集]? 是否有任何数学函数可以帮助我们从该数字中获取各个元素?
我想将一系列数字转换为一个单独的数字,该数字保留各个值以及它们的位置。例如,提供以下序列-
1,6,7,8,9,45,67
例如,如果应用简单的加法即 1+6+7+8+9+45+67,则会生成一个数字。但是从这个数字中,我们无法按其顺序提取每个单独的数字 [即 1,6,7,8,9,...]。
是否有任何方法可以在没有任何歧义的情况下实现此功能[即仅从数字中提取1个唯一的数字集]? 是否有任何数学函数可以帮助我们从该数字中获取各个元素?
http://www.icsharpcode.net/opensource/sharpziplib/
http://community.sharpdevelop.net/forums/p/8255/23219.aspx
使用zlib也很容易实现
12F
的数字:Base-16。再次强调,每个数字都可以根据位置唯一分离:如何?现在想象一种编号系统,其中每个数字的范围可以从(0)
(值为0)到(43)
(值为43),并且数字的书写方式为:(1)(42)(4)
。每个数字都可以根据位置唯一分离:如何? - user166390N
?如果有一种保存某些内容以便稍后检索的方法,您可以简单地将数字保存在字符串或数组中,这样更快,但它们将占用更多内存。 - Saeed AmiriS
,您首先通过某种映射将 S
的元素映射到正整数,然后执行我上面说的操作。您已经为整数证明了一个单射。通过应用您的映射,然后两次使用我的方法,您同样可以编码其元素为整数有限序列的任何有限序列。 - Steve Jessops
,我定义len(n)
为数字n的位数。len(s[0])
,
接下来的len(s[0])
位是数字s[0]
;
然后你附加len(s[1])
和s[1]
,以此类推。len(len(s[1]))
作为单个数字,将len(s[1])
放在1到9之间指定的数字位数中,然后再加上s[1]
;这适用于长达十亿位数字的非负整数。 - Danica这是一个基本的PHP实现哥德尔编码,由Steve Jessop在上面描述:
<?php
$sec = array(5,9,8,4);
$n = count($sec);
$max = max($sec);
$enc = encode($sec);
$dec = decode($enc, $n, $max);
echo "Input sequence: " . implode(",", $sec) . "\n";
echo "Output sequence: " . implode(",", $dec) . "\n";
echo "Godel number: " . $enc;
echo (PHP_INT_MAX/$enc < 20 ? " - too big to decode.\n" : "\n");
function encode($sec) {
$primes = array(2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53);
$enc = 1;
$i = 0;
foreach ($sec as $v) {
$enc = $enc * pow($primes[$i], $v+1);
$i++;
}
return $enc;
}
function decode($enc, $n, $max) {
$primes = array(2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53);
$sec = array();
for ($i = 0; $i < $n; $i++) {
for ($v = 2; $v <= $max+1; $v++) {
if ($enc/pow($primes[$i], $v) != round($enc/pow($primes[$i], $v))) {
break;
}
}
$sec[] = $v-2;
}
return $sec;
}
?>
如果您的数字范围是无限的,则无法实现。
自然数的幂集是不可数的。这意味着您无法提供数字集和数字之间的映射。
如果您的数字仅限于32位,那么您可以将数字连接成一个长二进制数字,并将它们作为字节序列存储,也许作为一个BigNum。
更新以检查0, 1情况。
用001分隔不同的数字。
为避免在您的数字内出现00时混淆,请每次出现0时将其替换为01。
要解码,请按001拆分。 将所有01替换为0。
这里使用了通用编码,例如Elias omega编码(或任何前缀编码--但通用编码是带有一些理想属性的前缀编码)。 前缀编码将一个比特序列(即一个数字)编码为一个前缀,基本上提供了必要的信息来确定其余数字由多少位组成。
1)使用编码表示序列中元素的数量。 2)然后使用编码表示每个元素。
我想到了另一个答案。使用平衡三进制对每个数字进行编码,每个三位数使用两个比特(例如,0=00;+1=01;-1=10)。剩余的比特对(例如,11)是元素结束标记,序列结束时重复。缺点:当预期有大量值时,比前缀代码的空间效率低;优点:1)在大多数小值情况下更节省空间;2)编码/解码更简单;3)直接表示负值。