【问题标题】:Understanding bit vector usage in finding unique character in a string [duplicate]了解位向量在字符串中查找唯一字符的用法[重复]
【发布时间】:2017-02-12 00:03:24
【问题描述】:

我有以下代码使用位向量在字符串中查找唯一字符。我们假设它是一个仅包含小写字母的 ASCII 字符集。

我很难理解下面位向量的使用。即使在通过程序进行调试并遵循更改之后,变量也会在每个循环之后进行。

// assuming that the characters range from a-z
static boolean isUniqueBitVector(String str) {
    int checker = 0;

    for(int i = 0; i < str.length(); i++) {
        int val = str.charAt(i) - 'a';

        if((checker & (1 << val)) > 0) {
            return false;
        } else {
            checker |= (1 << val);
        }
    }
    return true;
}

将 val(字符串中每个字符的 int 表示)左移 1 并与检查器(初始化为 0)进行“与”并在 else 块中进行“或”的目的是什么。

【问题讨论】:

  • "我们假设它是一个仅包含小写字母的 ASCII 字符集。"好的,但更重要的是,因为您使用的是 Java 的 Stringchar,它是仅带有小写 Basic Latin 字母的 Unicode 字符集。 if-throw 参数验证模式非常适合记录和执行假设,如果不成立,就会使您的算法无效。
  • 准备就绪后,请随意选择一个答案,以便将这个问题从未回答队列中删除。

标签: java string bit


【解决方案1】:

checker 是一个 32 位整数,我们分配其中的最低 26 位来存储每个字母 a-z 的标志。我们可以为此使用位,因为一个字母只能是非唯一的一次。

int val = str.charAt(i) - 'a'; 计算对应于当前字母的位的索引。这就是假设输入仅包含a-z 的地方。val 将是一个介于 0 和 25 之间的数字。

一般情况下,(1 &lt;&lt; val) 是对应于所选字母的位。 &lt;&lt; 是左移运算符。它用于将只有一个位的 1 向左移动 val 位置。所以例如1&lt;&lt;3 会是 8。事实上,左移相当于乘以 2 的幂。

(checker &amp; (1 &lt;&lt; val)) 验证所选位是否打开。 &amp; 运算符称为按位与。它结合了两个数字,并将两个都打开的任何位设置为打开。请记住,1 &lt;&lt; val 只打开了一个位。其结果和checker 将不为零的唯一方法是checker 已经打开了相同的位。在这种情况下,我们返回 false,因为一个字母被重复了。

在找到新字母的情况下,我们需要打开checker中的正确位。这就是checker |= (1 &lt;&lt; val); 所做的。按位或运算符 | 如果在任一操作数中打开,则打开结果中的位。同样,1 &lt;&lt; val 只打开了一位。因此 or 的结果是复制checker 并打开那一位(无论它是否已经打开)。

您在此处看到的所有操作都是非常常见的习语。希望我的解释在某种程度上对您有所帮助,因为您几乎肯定会在任何简单的代码中看到非常相似的东西。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-26
    • 1970-01-01
    • 1970-01-01
    • 2014-02-04
    • 2015-09-22
    • 1970-01-01
    相关资源
    最近更新 更多