java新手-尝试理解:checker |=(1<;<;val)

java新手-尝试理解:checker |=(1<;<;val),java,Java,下面的代码将检查字符串中是否有重复字符,但我不理解if子句: public static boolean isUniqueChars(String str) { int checker = 0; for (int i = 0; i < str.length(); ++i) { int val = str.charAt(i) - 'a'; if ((checker & (1 << val))

下面的代码将检查字符串中是否有重复字符,但我不理解if子句:

public static boolean isUniqueChars(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;
            checker |= (1 << val);
        }
        return true;
    }
public静态布尔值isUniqueChars(String str){
int-checker=0;
对于(int i=0;ichecker |=(1
1这将第‘val’位从右侧设置为1


1意思是在值
checker
(1
checker|=(1我也在翻阅这本书,最后在谷歌上搜索清楚的解释。最后我理解了这个概念

这里是方法

注意:

  • 在下面的代码中,我们将假定字符串仅为小写字母“a”到“z”。这将允许我们仅使用单个int

  • Java整数的大小为32

  • 小写字母的数量为26

  • 因此,我们可以在一个整数中清楚地设置0/1(真或假)值 十进制记数法

  • 它类似于bool[32]。 bool使用1个字节。因此需要32个字节来存储访问过的bool[32]

  • 位屏蔽是一种空间优化

  • 让我们开始:

  • 您正在遍历字符串中的所有字符
  • 假设在第i次迭代中,您发现了字符“b”。 您可以计算其基于0的索引
  • int val=str.charAt(i)-“a”;

    对于'b',它是1。即98-97

  • 现在使用左移位运算符,我们找到2^1=>2的值

  • (1其他答案解释了编码运算符的用法,但我认为它们没有触及此代码背后的逻辑

    基本上,代码
    1 1
    
  • 0&0->0
  • 1&0->0
  • 因此,checker当前在其相应字符已经出现的位置中有1个,这是if语句中表达式为true的唯一方式
    如果字符出现两次,导致1&1->1>0

    按位移位,其工作原理如下:

    示例:a=15(位表示:0000 1111)


    对于操作:
    a似乎我来晚了,但让我试着解释一下

    首先,和即操作:

    0 & 0 = 0
    1 & 0 = 0
    0 & 1 = 0
    1 & 1 = 1
    
    所以基本上,如果给你一点,你想知道它是1还是0,你只要用1来&它。如果结果是1,那么你有1,否则你有0。我们将使用下面的这个属性

    OR即|操作

    0 | 0 = 0
    1 | 0 = 1
    0 | 1 = 1
    1 | 1 = 1  
    
    所以基本上,如果你得到一点,你想对它做点什么,使输出总是1,那么你就用它做一个| 1

    现在,在Java中,
    int
    类型是4个字节,即32位。因此,我们可以使用
    int
    本身作为数据结构,以更简单的方式存储32个状态或布尔值,因为位可以是0或1,即false或true。因为我们假设字符串只由小写字符组成,所以int中有足够的空间来存储e 26个字符中的每一个都有一个布尔值

    所以首先我们初始化我们的数据结构,我们调用
    checker
    为0,它只不过是32个零:
    0000000000000000000000

    到目前为止还好吗

    现在我们检查字符串,对于每个字符,首先我们得到字符的整数表示

    int val = str.charAt(i) - 'a';
    
    我们从中减去
    a
    ,因为我们希望整数以0为基础。因此,如果VAL:

    a = 0 i.e. `0000000000000000000000`
    b = 1 i.e. `0000000000000000000001`
    c = 2 i.e. `0000000000000000000010`
    d = 4 i.e. `0000000000000000000100`
    

    如上图所示,a是32个零,但其余的字符有一个1和31个零。因此,当我们使用这些字符时,我们将每个字符左移1,即(1我一直在研究该算法,下面是我注意到的也会起作用的内容。当你用手练习时,它使算法更容易理解:

    public static boolean isUniqueChars(String str) {
        if (str.length() > 26) { // Only 26 characters
            return false;
        }
        int checker = 0;
        for (int i = 0; i < str.length(); i++) {
            int val = str.charAt(i) - 'a';
            int newValue = Math.pow(2, val) // int newValue = 1 << val
            if ((checker & newValue) > 0) return false;
            checker += newValue // checker |= newValue
        }
        return true;
    
    public静态布尔值isUniqueChars(String str){
    如果(str.length()>26){//仅26个字符
    返回false;
    }
    int-checker=0;
    对于(int i=0;i
    当我们得到
    val
    (0-25)的值时,我们可以通过
    val
    的值向右移动1,也可以使用2s的幂

    此外,只要
    ((checker&newValue)>0)
    为false,当我们将旧的checker值和
    newValue

    公共静态布尔值isUniqueChars(String str)相加时,就会生成新的checker值{
    
    public static boolean isUniqueChars(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;
            checker |= (1 << val);
        }
        return true;
    }
    
    int-checker=0; 对于(int i=0;ichecker |=(1)它与
    public static boolean isUniqueChars(String str){boolean checker[]=new boolean[str.length())];for(int i=0;i
    但标志不是布尔数组,而是以位形式存储在整数变量中。由于此算法使用了布尔数组,因此具有O(n)空间复杂度。使用此位向量可减少空间使用量。简单地说,genius;)+1有帮助!谢谢非常有说明性!谢谢。
     if ((checker & (1 << val)) > 0) 
                    return false;
    
    0 | 0 -> 0
    0 | 1 -> 1
    1 | 0 -> 1
    1 | 1 -> 1
    
    check = 0000 0000 0000 0000 0000 1000 1000 0000   |  
    'b'   = 0000 0000 0000 0000 0000 0000 0000 0010 
     ----------------------------------------------
    result= 0000 0000 0000 0000 0000 1000 1000 0010
    
    checker |= (1 << val);  // checker = checker |  (1 << val);
    
    checker = checker | (1 << val)
    
    if ((checker & (1 << val)) > 0) 
    
    0 & 0 = 0
    1 & 0 = 0
    0 & 1 = 0
    1 & 1 = 1
    
    0 | 0 = 0
    1 | 0 = 1
    0 | 1 = 1
    1 | 1 = 1  
    
    int val = str.charAt(i) - 'a';
    
    a = 0 i.e. `0000000000000000000000`
    b = 1 i.e. `0000000000000000000001`
    c = 2 i.e. `0000000000000000000010`
    d = 4 i.e. `0000000000000000000100`
    
    a = 1 i.e. `0000000000000000000001`
    b = 2 i.e. `0000000000000000000010`
    c = 4 i.e. `0000000000000000000100`
    d = 8 i.e. `0000000000000000001000`
    
    checker = checker | (1 << val);
    
    checker & (1 << val)
    
    public static boolean isUniqueChars(String str) {
        if (str.length() > 26) { // Only 26 characters
            return false;
        }
        int checker = 0;
        for (int i = 0; i < str.length(); i++) {
            int val = str.charAt(i) - 'a';
            int newValue = Math.pow(2, val) // int newValue = 1 << val
            if ((checker & newValue) > 0) return false;
            checker += newValue // checker |= newValue
        }
        return true;
    
    public static boolean isUniqueChars(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;
            checker |= (1 << val);
        }
        return true;
    }