我正在寻找一个用于对位串进行哥德尔编号的概念,即用于任意二进制数据。
方法1(失败):简单地将二进制数据解释为无符号整数的数据
这失败了,因为例如两个不同的字符串"01"
和"001"
都表示相同的整数1
。
有没有一种标准的方法可以做到这一点?通常在哥德尔编号中包括或排除0?
答案 0 :(得分:1)
一个超级简单的解决方案是将1
添加到二进制数据中,然后将结果解释为无符号整数值。这样,在位串的左侧没有0
个数字丢失。
插图如何运作:
命令位串的一种显而易见的方法是首先按长度排序,然后按字典顺序排序:
+------------+
| bit string |
+------------+
| ε |
| 0 |
| 1 |
| 00 |
| 01 |
| 10 |
| 11 |
| 000 |
| 001 |
| 010 |
| 011 |
| 100 |
| 101 |
| 110 |
| ... |
+------------+
(ε
表示没有数字的空字符串。)
现在我们向此表添加索引号n
,从1开始,然后查看索引号n
的二进制表示。我们将在那里做一个很好的发现:
+------------+--------------+-------------+
| bit string | n in decimal | n in binary |
+------------+--------------+-------------+
| ε | 1 | 1 |
| 0 | 2 | 10 |
| 1 | 3 | 11 |
| 00 | 4 | 100 |
| 01 | 5 | 101 |
| 10 | 6 | 110 |
| 11 | 7 | 111 |
| 000 | 8 | 1000 |
| 001 | 9 | 1001 |
| 010 | 10 | 1010 |
| 011 | 11 | 1011 |
| 100 | 12 | 1100 |
| 101 | 13 | 1101 |
| 110 | 14 | 1110 |
| ... | ... | ... |
+------------+--------------+-------------+
这非常好用,因为n
的二进制表示(以非常明显的方式排序时每个位串的索引)只不过是原始位串前面的1
然后将整个事物解释为无符号整数值。
如果您更喜欢基于0的Goedel编号,则从结果整数值中减去1。
伪代码中的转换公式:
// for starting with 1
n_base1 = integer(prepend1(s))
s = removeFirstDigit(bitString(n_base1))
// for starting with 0
n_base0 = integer(prepend1(s)) - 1
s = removeFirstDigit(bitString(n_base0 + 1))
答案 1 :(得分:0)
原始哥德尔编号使用了素数和符号的唯一编码。如果要对包含“0”和“1”的字符串执行此操作,则需要“0”(例如1)和“1”(例如2)的正代码。然后编号“01”是
21 * 32
,而“001”的编号是
21 * 31 * 52
对于较长的字符串,请使用下一个素数。但是,请注意哥德尔编号目标并未包含任何实际考虑因素,他只需将编号作为证明其定理的工具。在实践中,对于相当短的字符串,您将超出您的语言中的整数范围,因此您需要使用内置任意大整数的语言(如Scheme)或支持语言的bignums而不内置它们的库。