关于Java:获取字符串的int表示形式

关于Java:获取字符串的int表示形式

Getting an int representation of a String

我正在寻找一种创建任意字母数字字符串的int \ long表示形式的方法。 哈希代码不会这样做,因为我负担不起哈希冲突,即表示必须是唯一且可重复的。

数字表示将用于执行有效的(希望的)比较。 数字键的创建将花费一些时间,但是只需要执行一次,而我需要对其进行大量的比较-希望比比较原始String快得多。

关于更快的字符串比较的任何其他想法也将受到赞赏...


除非您的字符串长度受限制,否则您将避免冲突。

整数(2 ^ 32)有4294967296个可能的值。如果您的字符串包含4个以上的ASCII字符或两个以上的unicode字符,则可能的字符串值多于可能的整数值。对于每个可能的5个字符串,您不能有一个唯一的整数值。长值有更多可能的值,但它们只会为每个可能的8个ASCII字符字符串提供唯一值。

哈希码可用于两个步骤:首先查看哈希码是否匹配,然后检查整个字符串。对于大多数不匹配的字符串,您只需要执行第一步,这确实非常快。


您不能仅从哈希码开始,如果哈希码匹配,是否逐字符进行比较?


弦多久了?如果它们很短,则可以通过将字符视为基数36(26 + 10)中的数字来生成唯一的ID,该数字形成n位数字,其中n是字符串的长度。另一方面,如果字符串足够短以允许这样做,则直接比较将不再是问题。

否则,您将必须生成无冲突的哈希,只有在事先知道完整的问题空间时(即,如果您知道所有可能出现的字符串),才能完成此操作。您将要看一下完美哈希,尽管找到一个我知道的完美哈希函数的唯一可行算法是概率性的,所以理论上仍然可能发生冲突。

找到这种功能可能还有其他方法。克努斯(Knuth)在TAoCP中称其为"相当有趣的……难题",但他也没有给出算法。

通常,您提供的信息太少,无法找到不需要以某种方式探测整个问题空间的算法。这确实意味着问题的运行时间是指数级的,但可以使用机器学习启发式方法解决。我不确定这是否适合您的情况。


一天结束时,单个字母数字字符至少具有36个可能的值。如果包含标点符号,小写字母等,则可以轻松传递72个可能的值。

允许您快速比较字符串的非冲突数字必然会随着字符串的长度呈指数增长。

因此,您首先必须确定要比较的最长字符串。假设它的长度为N个字符,并且假设您只需要大写字母和数字0-9,那么您需要使用一个整数表示法,该整数可以高达
36 ^ N

对于长度为25(公用名字段)的字符串,您最终需要一个130位的二进制数。

如果将其组合为32位数字,则需要4。然后可以比较每个数字(与遍历字符串相比,四个整数比较无需花费时间)。我会推荐一个大数字库,但是对于这种特殊情况,我很确定您可以编写自己的并获得更好的性能。

如果您想每个字符处理72个可能的值(大写,小写,数字,标点符号...),并且需要10个字符,那么您将需要62位-两个32位整数(或者如果是,则为一个64位)支持64位计算的系统)

但是,如果您不能限制字符串中的数字(即可以是256个字母/数字/字符/等中的任何一个)并且您不能定义字符串的大小,则直接比较字符串是唯一的方法,但有一条捷径。

将字符串的指针强制转换为32位无符号整数数组,然后一次将字符串比较4个字节(或在64位处理器上一次比较64位/ 8字节)。这意味着一个100的字符串最多只需要25个比较就可以找到更大的一个。

您可能需要重新定义字符集(并转换字符串),以便为优先级较高的字符分配接近0的值,为优先级较低的字符分配接近255的值(反之亦然,具体取决于您如何比较它们) 。

祝好运!

-亚当


也许:

1
2
3
String y ="oiu291981u39u192u3198u389u28u389u";
BigInteger bi = new BigInteger(y, 36);
System.out.println(bi);

只要它是一个哈希函数,无论是String.hashCode(),MD5还是SHA1,除非对字符串的长度有固定的限制,否则冲突都是不可避免的。从无限组到有限组进行一对一的映射在数学上是不可能的。

退一步,避免碰撞绝对必要吗?


一开始的几个问题:

  • 您是否测试过简单的字符串比较太慢?
  • 比较的样子如何('ABC'=='abc'或'ABC'!='abc')?
  • 您必须比较多少个字符串?
  • 您必须进行多少比较?
  • 您的字符串看起来如何(长度,字母大小写)?
  • 据我记得,Java中的String是一个对象,两个相同的字符串指向同一对象。

    因此,比较对象也许就足够了(可能已经以这种方式实现了字符串比较)。

    如果这样做没有帮助,则当第一个元素为length时,您可以尝试使用字符串对象的Pascal实现;如果字符串的长度不同,则应该节省一些CPU时间。


    String length may vary, but let's say 10 characters for now.

    在那种情况下,为了保证唯一性,您必须使用某种大整数表示形式。我怀疑对大整数进行比较会比首先进行字符串比较快得多。我将在这里讲别人的话,使用某种哈希,然后在哈希匹配的情况下检查原始字符串以清除所有冲突。

    无论如何,如果您的字符串大约是10个字符,我怀疑比较一堆32位哈希值是否会比直接字符串比较快得多。我认为您必须问自己,是否真的值得增加其他复杂性。


    您为什么不做类似1stChar +(10 x 2ndChar)+ 100 x(3rdChar)....的操作,在此您使用每个字符的简单整数值,即a = 1,b = 2等,或者只是如果不是字母,则为整数值。这将为每个字符串提供唯一的值,即使对于两个相同字母但顺序不同的字符串也是如此。

    当然,如果您需要担心Unicode而不仅仅是ASCII会变得更加复杂,并且如果您需要使用长字符串,则数字可能会变大。

    标准的Java字符串比较功能肯定不够高效吗?


    似乎MD5哈希可以正常工作。哈希冲突的风险极不可能。根据字符串的长度,生成int / long的哈希会很快遇到最大值问题。


    假设"字母数字"表示字母和数字,则可以将每个字母/数字视为基数36。不幸的是,大字符串会导致数字快速增长,因此您不得不求助于效率不高的大整数。

    如果进行比较(即搜索特定的字符串)时字符串通常不同,则散列可能是最好的选择。一旦获得潜在的成功,就可以确定字符串比较。精心设计的哈希将使冲突极为罕见。


    如果您不想发生碰撞,请尝试一些疯狂的事情,例如SHA-512。我不能保证不会发生碰撞,但是我认为它们尚未发现任何碰撞。


    你的弦多大?任意长的字符串都不能压缩为32/64位格式。


    你的弦多久了?除非您选择一个比字符串更长的int表示形式,否则无论您使用哪种转换,都将始终可能发生冲突。因此,如果使用32位整数,则只能唯一表示最多4个字节的字符串。


    推荐阅读

      linux命令行执行py?

      linux命令行执行py?,系统,环境,官网,一致,文件,程序,脚本,源文件,后台,终端,l

      linux查看执行命令?

      linux查看执行命令?,系统,服务,情况,信息,命令,暂停,标准,概念,实时,第一,lin

      linux命令连续执行?

      linux命令连续执行?,连续,通信,工具,数据,代码,命令,设备,系统,发行,情况,如

      linux执行命令卡住?

      linux执行命令卡住?,系统,环境,密码,数据,信息,分析,软件,异常,服务,命令,Lin

      linux拼接字符串命令?

      linux拼接字符串命令?,系统,工作,代码,工具,名称,信息,地址,时间,数据,命令,l

      linux命令执行不动了?

      linux命令执行不动了?,系统,电脑,数据,管理,信息,密码,命令,环境,地方,分析,l

      linux脚步中执行命令?

      linux脚步中执行命令?,工具,代码,命令,名称,系统,连续,环境,发行,文件,终端,l

      linux后台执行命令?

      linux后台执行命令?,暂停,状态,系统,服务,标准,命令,后台,地方,进程,终端,lin

      linux执行权限命令行?

      linux执行权限命令行?,地址,电脑,系统,数字,工作,权限,目录,文件,新增,信息,L

      linux命令的执行时间?

      linux命令的执行时间?,时间,系统,周期,信息,命令,设备,环境,地址,基础,进程,l

      添加字符串命令linux?

      添加字符串命令linux?,情况,名称,文件,位置,名字,地方,连续,信息,命令,内容,L

      程序执行linux命令?

      程序执行linux命令?,系统,工作,地址,环境,信息,管理,命令,文件,目录,程序,lin

      linux执行2个命令?

      linux执行2个命令?,工作,系统,基础,命令,基础知识,信息,管理,在线,概念,第一

      linux命令批量执行?

      linux命令批量执行?,系统,代码,工作,周期性,数据,定期,环境,命令,文件,脚本,l

      linux二进制执行命令?

      linux二进制执行命令?,系统,工作,情况,代码,信息,位置,地址,命令,文件,目录,L

      linux执行退出命令?

      linux执行退出命令?,档案,状态,工作,命令,信息,地址,电脑,系统,编辑,文件,lin

      linux中后台执行命令?

      linux中后台执行命令?,系统,状态,暂停,灵活,电脑,网络,服务,第一,名字,命令,l

      linux常用的执行命令?

      linux常用的执行命令?,系统,地址,工作,基础,标准,命令,工具,环境,信息,代码,L

      linux执行线程命令?

      linux执行线程命令?,系统,工作,线程,软件,服务,管理,信息,环境,名称,命令,lin

      linux执行多条命令?

      linux执行多条命令?,数据,通信,管理,系统,命令,标准,信息,工具,代码,环境,Lin