我试图开发能够改变我的字符串转换成一种独特的积分值,这意味着,比方说是单词“帐户”有0891加密的数值并没有其他字可能被转换为0891具有相同的转换过程的系统,但是,它并不需要能够产生的整数转换回字符串。
同时它将依赖于字结构规则,意思的词语,如“精度”和“通知”将具有比0891和诸如“一”,“算盘”和“缩写”大的产生的数量将有所产生的数小于0891。
本申请的目的是为类似于索引或主键。 为什么我不使用增量指标的原因是出于安全目的,是由于索引依赖于数据集合中的数
(Eg)的
[0] A, [1] B, [2] C, [3] D, [4] E, [5] F
以上的字母具有每一个对应索引,E具有4索引
但是,如果数据突然增加或再排序下降
[0] A, [1] AA, [2] AAB, [3] C, [4] D, [5] DA, [6] DZ, [7] E, [8] F
E现在有7个指标
每个字都必须具有唯一独立的积分等同的,都有相应的权重。
我需要知道,如果存在一个算法,能够做到以上。
任何帮助将不胜感激。
Answer 1:
这是不可能的,你给,除非你强加最大长度的限制。
假定k("a")
和k("b")
是这两个字符串的代码。
有了您的约束,你正在寻找其间的下降这两个值的唯一的整数,但k("a") < k("a....a") < k("b")
由于存在的风格的字符串的无限数量"a....a"
(和"akjhdsfkjhs"
),这将需要适应其间两个代码,这样的保序通常,唯一的,固定长度的代码串就不能存在的任意长度。 因为你需要尽可能多的整数作为字符串,字符串,因为不被长度为界这可不行。
无论是拖放一般的(所以不允许插入新的字符串),唯一的(允许collissions - 例如使用的前四个字母的代码!),无界的长度(以如3个字符)或保序性能。
Answer 2:
为简单起见,我假设a
以z
都允许的话唯一的字符。
让我们把人数达到长2个字符串:
String Value
a 0
aa 1
ab 2
...
az 26
b 27
ba 28
bb 29
...
bz 53
c 54
...
现在,通过看,你应该能够理解的是,以确定任何给定长度的短串的抵消,你需要允许的最大长度。 假设我们知道这个号码。
对于算法简单,我们希望在27开始:(随意揣摩它从0开始,你需要一些特殊情况下)
String Value
a 27
aa 28
ab 29
...
所以,本质上,最左边的字符贡献值27*(1-26)
为AZ)和下一个字符的权利,如果存在的话,有助于1-26
(为AZ)为一个字符串值。
现在,这可以概括地说,最左边的数字将有助于(1-26)*27^(len-1)
下(1-26)*27^(len-2)
依此类推,直到(1-26)*27^0
。
这使我对一些Java代码:
long result = 0;
for (int i = 0; i < s.length(); i++)
result += pow(27, MAX_LENGTH - i - 1)*(1 + s.charAt(i) - 'a');
测试输出:
a = 150094635296999121
aa = 155653695863554644
aaa = 155859586995649293
aaaa = 155867212593134280
aaaaa = 155867495022670761
abacus = 161447654121636735
abbreviation = 161763445236432690
account = 167509959568845165
accuracy = 167554723653128367
announcement = 230924421746611173
z = 3902460517721977146
在线演示 。
是的,这些都是刚刚达到13名长度的字符串一些相当大的数字,但是,没有一个实际的字典顺序分配号码的话,你不能做任何好转(但您可以在0,这是开始,相对来说,差小),由于有该字母序列的许多可能性。
Answer 3:
的唯一性,开始的字母分配素数: A -> 2, B -> 3, C -> 5, D -> 7
等
要计算一个词一个给定的字母的“钥匙”,提高黄金在字中的位置索引的力量。 为了让全词的“钥匙”,乘所有的字母键一起。
例如字CAB:
C -> 5 ^ 1 = 5
A -> 2 ^ 2 = 4
B -> 3 ^ 3 = 81
CAB -> 5 * 4 * 81 = 1620.
没有其他的字都不会给你1620的一个关键。
注意:您不必先从A - > 2或者为了你只要跟踪映射的分配素数的字母的字符。 还要记住的是这个结果会得到大的非常快。
然而,牢记其他意见有关安全 - 这是不是一个特别安全的算法。
Answer 4:
如果你没有对这些整数可以占用的字节数的限制,则每个字符的底层(如ASCII)字节代码会给你一个整数表示。 同样地,分配0 = A,1 = B到Z = 25,然后这个词本身是在基座26的整数。
Answer 5:
分配一个唯一的黄金价值递增的顺序(没有必要的顺序)的每个字母。
请注意:由于素数的乘积是一个独特的结果只能由这些数字相乘 ,它会给你的每一个单词的唯一值。
算法:
int hash = 0;
forEach (int i = 0 ; i < word.length ; i++)
{
hash *= (prime[c[i]] ** (length - i));
}
素 - 一个数组以存储对应于每一个素值
供电以(长 - 1),得到值到使该字符发生维持字典顺序的地方。
该算法将给予该会溢出你的阵列足够大的值 。
另外: 话会更小的长度可能比一些话具有更大的长度给予较低的值,它可能会影响你的字典顺序 ,但我不知道为什么你要一本字典顺序的独特性将在这里保持。
Answer 6:
你可以这样做:
SEPARETOR = '000'
string_to_hash = "some_string"
hashed_result = int(SEPARETOR.join(list(str(ord(character)) for character in string_to_hash)))
请享用!
Answer 7:
是的,但大多没有。
是在随机的答案。 通过建立一个基地26(或所有ASCII基地128),你可以在理论上唯一散列每个字符串。
在另一方面,这是不切实际的,不仅会数受到太大的大多数语言,而且这可能会是一个令人难以置信的耗时的过程。 此外,如果字符串被允许是无限的,那么的形式对角论证法可应用于也“破”这种算法。 这是不可能创建一组与基数ALEPH酮(字符串)到一组基数ALEPH空(整数)中的一对一的映射。
文章来源: String to unique integer hashing