Bitshift - 需要帮助来理解代码

时间:2013-04-09 18:39:39

标签: java bitwise-operators bit-shift

我只是想学习按位/移位操作。

我遇到了以下程序,但是不理解AND条件部分(检查器&(1<<< val)在下面的程序中。什么时候最终值大于0?有人可以解释什么发生在那里?

示例输入: XYZZ

示例输出:

8388608Value 0checker 最终值

16777216Value 8388608checker 最终值

33554432Value 25165824checker 最终值

33554432Value 58720256checker 33554432最终值

public static boolean isUniqueChars(String str) {
        int checker = 0;
        for (int i = 0; i < str.length(); i++) {
            int val = str.charAt(i) - 'a';

            System.out.println((1 << val) + "Value");
            System.out.println((checker) + "checker");
            System.out.println(((checker & (1 << val))) + "final value\n");

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

}

2 个答案:

答案 0 :(得分:6)

好的,只是为了确保你知道发生了什么:

int val = str.charAt(i) - 'a';

假设使用英文字母,这将取您(小写)字母的char值并减去97('a'的char值)以产生0到25之间的数字。不要对大写字符尝试此功能,除非在.toLowerCase()

之后添加.charAt(i),否则会出现错误

1 << val向左移动1 val个位置。例如,对于'x'(120 - 97 = 23,所以...... 1 << 23),二进制表示将为00000000010000000000000000000000

好的,到目前为止和我在一起?

一开始,检查器全部为0位,因此它是00000000000000000000000000000000

所以...让我们输入数字而不是变量。对于我们的x检查,checker & (1 << val)变为00000000000000000000000000000000 & 00000000010000000000000000000000等于00000000000000000000000000000000,因为第23位未设置为检查器。

因此,处理x后,我们将第23位添加到检查器并转到下一个字母:y这一次,checker & (1 << val)变为00000000010000000000000000000000 & 00000000100000000000000000000000,等于{ {1}}因为第24位未在检查器中设置。

对于第一个00000000000000000000000000000000z变为checker & (1 << val)等于00000000110000000000000000000000 & 00000001000000000000000000000000,因为第25位未在检查器中设置。

对于第二个00000000000000000000000000000000z变为checker & (1 << val),等于00000001110000000000000000000000 & 00000001000000000000000000000000(十进制33554432或2 ^ 25),因为第25位 设置在检查器中,00000001000000000000000000000000现在为> 0,函数返回true

答案 1 :(得分:1)

我认为你的功能是检查输入字符串中的所有字符是否不同。如果相同(小写)字符出现多次,则返回false。

checker变量用作一种位图,用于累积到目前为止出现的字符。数据类型int由32位组成,足以为每个字符分配一位(26)。

该函数循环遍历str的所有字符。行int val = str.charAt(i) - 'a';根据字符('a'=&gt; 0,'b'=&gt; 1,'c'=&gt; 2等)为val分配某种序数值。 )。

表达式1 << val将(0..25)范围内的每个val分配给它的位位置。因此,字符'a'被映射到1&lt;&lt;&lt; 0 == 1 == 00000001,字符'd'被映射1&lt;&lt; 3 == 00001000,依此类推。每个字符都分配了唯一的位掩码,只有一位设置,所有其他位清零。

表达式(checker & (1 << val))是&gt; 0如果在1 << val中设置的位也设置在检查器中(请注意,检查器可能设置了多个位)。如果是这样,当前迭代的字符出现得更早,函数返回false。否则,当前字符的位掩码通过按位OR运算符|添加到充当累加器的检查器。如果所有字符都已循环并且没有两次遇到任何字符,则该函数返回true。请注意,该函数可能会忽略大写和其他字符。