如果您处理的是小数字,没问题。每次组成数字时,您都在用数字做同样的事情:数字是从 0 到 9 的数字,而完整的数字是它们的组合:
- 本身就是一个数字
- 对于给定的数字是唯一的
- 让您轻松验证数字是否在里面
问题是数字必须有一个上限,例如 10 代表数字。为简单起见,我们假设 1000,类似的组合数可能是:
n1*1000^k + n2*1000^(k-1) + n3*1000^(k-2) ... + nk*1000^(0)
所以如果你有数字 33、44 和 27,你会得到:
33*1000000 + 44*1000 + 27,也就是数字N:33044027
当然你可以用更大的限制做同样的事情,像 256,1024 或 65535 这样的二进制,但它增长得很快。
如果可能的话,一个更好的主意是将其转换为带有一些分隔符的字符串(字符串仍然是数字!)(以 11 为底的数字,即 10 个普通数字 + 1 个分隔数字)。这更灵活,因为没有上限。想象一下使用数字 0-9 + 分隔数字“a”。您可以获得以 11 为底的数字 33a44a27。通过将其转换为以 10 为底或以 16 为底的数字,您可以获得一个普通的计算机编号(如果我猜对了,则为 65451833)。然后将 65451833 转换为 11 进制 (base11) 33a44a27,并按数字 'a' 拆分,即可得到原始数字进行测试。
编辑:可变基数?
当然,这在以 17 为基数(16 位+分隔符)的数字上会更好。但我怀疑有更优化的方法,例如如果路径中的数字是唯一的,你添加的数字越多,剩余的越少,基数就越短。你能想象一个数字,其中第一个数字以 20 为底,第二个数字以 19 为底,第三个数字以 18 为底,以此类推?这可以做到吗?嗯?
在这个变化的基础世界中(在 10 个节点图中),路径 n0-n1-n2-n3-n4-n5-n6-n7-n8-n9 将是
n0*10^0 + (n1*9^1)+(偏移量:1) + n2*8^2+(偏移量:18) + n3*7^3+(偏移量:170)+...
偏移量1:10-9=1
偏移量2:9*9^1-1*8^2+1=81-64+1=18
偏移量3:8*8^2-1*7^3+1=343-512+1=170
如果我做对了,在这个小提琴中:http://jsfiddle.net/Hx5Aq/ 最大的数字路径是:102411
var path="9-8-7-6-5-4-3-2-1-0"; // biggest number
o2=(Math.pow(10,1)-Math.pow(9,1)+1); // offsets so digits do not overlap
o3=(Math.pow(9,2)-Math.pow(8,2)+1);
o4=(Math.pow(8,3)-Math.pow(7,3)+1);
o5=(Math.pow(7,4)-Math.pow(6,4)+1);
o6=(Math.pow(6,5)-Math.pow(5,5)+1);
o7=(Math.pow(5,6)-Math.pow(4,6)+1);
o8=(Math.pow(4,7)-Math.pow(3,7)+1);
o9=(Math.pow(3,8)-Math.pow(2,8)+1);
o10=(Math.pow(2,9)-Math.pow(1,9)+1);
o11=(Math.pow(1,10)-Math.pow(0,10)+1);
var n=path.split("-");
var res;
res=
n[9]*Math.pow(10,0) +
n[8]*Math.pow(9,1) + o2 +
n[7]*Math.pow(8,2) + o3 +
n[6]*Math.pow(7,3) + o4 +
n[5]*Math.pow(6,4) + o5 +
n[4]*Math.pow(5,5) + o6 +
n[3]*Math.pow(4,6) + o7 +
n[2]*Math.pow(3,7) + o8 +
n[1]*Math.pow(2,8) + o9 +
n[0]*Math.pow(1,9) + o10;
alert(res);
所以 N5,7->6... => 1,2,3,4,5,6...(如果从第一个开始,则可以恢复且唯一)