【问题标题】:Impossible for me to understand a method of string search as described. What is uFFFF?我不可能理解所描述的字符串搜索方法。什么是 uFFFF?
【发布时间】:2012-02-20 14:47:17
【问题描述】:

我正在阅读有关在已排序的字符串数组中搜索(范围)字符串的内容。

上面写着:

如果要查找所有以“h”开头的字符串,可以运行 对字符串“h”和“h\uFFFF”进行二进制搜索。这给了所有 所有以“h”开头的键的波段索引。请注意,一个 二进制搜索可以返回字符串所在的索引,即使 它实际上不在数组中。

我不明白这一段的任何内容。

什么是h\uFFFF 它如何帮助/在二分搜索中使用,最后一句话是否也意味着即使这个搜索也是错误的?

请帮助理解这里所说的内容?

【问题讨论】:

  • \uFFFF 是 unicode 字符的最大值,不用作可打印字符
  • '\uFFFF' 是代码点 U+FFFF 的转义序列,the stanard 保证它不是字符。在您正在阅读的其他地方是否定义了它的某些特殊用途?
  • @Sam Dehaan: "\uFFFF 是 unicode 字符的最大值"...自从 Unicode 3.1 以来,有超过 65 536 个代码点和一个 Java char 不足以表示新的代码点。例如,Unicode 字符“MUSICAL SYMBOL G CLEF”的 Unicode 代码点为 0x0001D11E(远大于 0xFFFF),需要两个 Java char 来表示:“\uD8334\uDD1E”。这个 SNAFU 源于 Java(以及它的 char 原始类型)是在 Unicode 3.1 出现之前定义的。总之:不,\uFFFF 绝对是 NOT Unicode 代码点的最大值。

标签: java string performance algorithm binary-search


【解决方案1】:

\uFFFF 是在 16 位“字母”中排在最后的“字符”,即在任何有效的字母、字符或特殊符号之后。

当您在排序数组中对字符串进行二进制搜索时,您会找到可以插入该字符串的位置。当您有多个相同的字符串时,您会在第一个字符串之前获得一个位置。当您在字符串后面附加“字母表的最后一个字母”时,插入点将位于相同字符串的最后一个之后,从而在排序数组中为您提供一系列相同的字符串。

想象一下:假设你的文字中不允许使用字母Z。现在你有一个排序的字符串数组:

0   1   2   3   4   5   6
aab abb abc abc abd bcx bdy

如果您搜索abc,二分搜索会告诉您可以插入它的第一个位置,即 2。如果您搜索 abcZ,但是,二分搜索将返回 4,因为 abcZ 按字母顺序排列在abc 之后。这让您知道字符串 abc 占用了 2(包括)和 4(不包括)之间的范围。如果两次搜索都返回相同的数字,则表明该字符串不存在于数组中。

在您引用的段落中,\uFFFF 在我的示例中扮演“禁止字母 Z”的角色。

【讨论】:

  • 我认为你的例子不正确。你有 abc{2} 是 root 的右孩子,而且你有 abc{3} 是 aab {root 的左孙}
  • 在二分搜索中,左孩子是2*i+1,右孩子是2*i+2。这就是我的意思。我更正了我的评论
  • @user384706 我认为您误解了我的示例:那里没有根 - 实际上,没有任何层次结构。它只是一个简单的字符串数组,按字母升序排序。
  • @user384706 我想你说的是binary heap,而不是binary search。二分查找将一个数组分成两半,检查值,并决定是继续向当前中点的左侧还是右侧搜索,找到结果时继续,或者知道值不存在时继续。
  • 你是对的。但是如果abc已经在数组中,为什么搜索会返回2?它不应该返回3吗?它搜索abc并进入中间即3,它就在那里
【解决方案2】:

\uFFFF 是 Java 中可能的最大字符。由于字符串已排序,搜索h 将找到范围的开头,而h\uFFFF 将找到结尾(假设此处为unicode 字符串),因为第二个字符不能大于\uFFFF。即使它不能完全匹配字符串,搜索也会返回目标 所在位置的索引,即使它实际上并不存在。

更新:\uFFFF 是 16 位块中最大可能的可排序 unicode 字符,如果您使用 32 位块,请使用 U+10FFFF(无论在 Java 中是什么)。我个人从未在 Java 中使用过 32 位 unicode 块。请参阅the 5.2.0 spec 的第 16.7 节。

U+FFFF 和 U+10FFFF。这两个非字符代码点具有 与最大代码单元值相关联的属性 特定的 Unicode 编码形式。 在 UTF-16 中,U+FFFF 是关联的 具有最大的 16 位代码单元值 FFFF 。 U+10FFFF 是 与最大的合法 UTF-32 32 位代码单元值相关联, 10FFFF 。此属性呈现这两个非字符代码点 作为哨兵用于内部目的。 例如,它们可能是 用于指示列表的结尾,表示索引中的值 保证高于任何有效字符值,以此类推

【讨论】:

  • 所以这个符号\uFFFF 可以帮助您在String 中传递一个十六进制字符?
  • 这取决于语言,但它“意味着”被称为“FFFF”的 unicaode 字符。 SOftof 喜欢 ASCII 0xFF...
  • 看我的最后一句话理解摘录的最后一句话。
  • @AndrewWhite:再一次; ) "\uFFFF" 是最大可能的 unicode 字符"... 一点也不。这是完全错误的。最新版本的 Unicode 定义了大约 109 000 个字符。而且,尽管普遍认为,Java char 绝对 NOT 足以表示 Unicode 字符。基本多语言平面中有 65 536 个代码点,但自 Unicode 3.1 以来,已添加了额外的平面添加。在 Java 中,您需要两个 char 来对 BMP 之外的字符进行编码,例如:*“\uD834\uDD1E”(Unicode 代码点 0x0001D11E,远高于 0xFFFF)。
  • @Andrew White:你一直忽略这一点,而不是承认你的错误并编辑你的问题,你试图改变我所说的。但是 facts 仍然存在(这是事实的有趣之处,您不能与它们争论;)您写道:“\uFFFF 是最大可能的 unicode 字符”,其中是公然错误的。所以,基本上安德鲁,你在这里告诉任何人 0x1D11E 小于 0xFFFF?所以,为了让大家明白,你坚持你的两个断言:“uFFFF 是最大可能的 Unicode 字符”“0x1DD11E 不高于 0xFFFF”?跨度>
【解决方案3】:

Java 中的\uFFFF 序列表示具有Unicode 代码点U+FFFF 的字符。但是,代码点根本不编码字符:

U+FFFF 用于表示保证不是字符的数值,用于索引末尾的最终值等用途。

请参阅以下参考资料:Unicode Technical Report #16this Unicode character chartthis character definition

【讨论】:

    【解决方案4】:

    正如其他答案所指定的,搜索h 将找到以h 开头的字符串范围的开头,而h\uFFFF 将找到以h 开头的字符串范围的结尾(不包括)在您的数据集中。

    最后一句话的意思是搜索h\uFFFF 会告诉你在哪里插入这样一个字符串,如果它在你的数据中不存在,这就是为什么它给你你的范围的唯一结束。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-02-20
      • 2013-12-03
      • 1970-01-01
      • 2013-08-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多