Explain the use of a bit vector for determining if all characters are unique

前端 未结 12 1810
野性不改
野性不改 2020-12-04 04:23

I am confused about how a bit vector would work to do this (not too familiar with bit vectors). Here is the code given. Could someone please walk me through this?

         


        
12条回答
  •  眼角桃花
    2020-12-04 04:59

    public static void main (String[] args)
    {
        //In order to understand this algorithm, it is necessary to understand the following:
    
        //int checker = 0;
        //Here we are using the primitive int almost like an array of size 32 where the only values can be 1 or 0
        //Since in Java, we have 4 bytes per int, 8 bits per byte, we have a total of 4x8=32 bits to work with
    
        //int val = str.charAt(i) - 'a';
        //In order to understand what is going on here, we must realize that all characters have a numeric value
        for (int i = 0; i < 256; i++)
        {
            char val = (char)i;
            System.out.print(val);
        }
    
        //The output is something like:
        //             !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ
        //There seems to be ~15 leading spaces that do not copy paste well, so I had to use real spaces instead
    
        //To only print the characters from 'a' on forward:
        System.out.println();
        System.out.println();
    
        for (int i=0; i < 256; i++)
        {
            char val = (char)i;
            //char val2 = val + 'a'; //incompatible types. required: char found: int
            int val2 = val + 'a';  //shift to the 'a', we must use an int here otherwise the compiler will complain
            char val3 = (char)val2;  //convert back to char. there should be a more elegant way of doing this.
            System.out.print(val3);
        }
    
        //Notice how the following does not work:
        System.out.println();
        System.out.println();
    
        for (int i=0; i < 256; i++)
        {
            char val = (char)i;
            int val2 = val - 'a';
            char val3 = (char)val2;
            System.out.print(val3);
        }
        //I'm not sure why this spills out into 2 lines:
        //EDIT I cant seem to copy this into stackoverflow!
    
        System.out.println();
        System.out.println();
    
        //So back to our original algorithm:
        //int val = str.charAt(i) - 'a';
        //We convert the i'th character of the String to a character, and shift it to the right, since adding shifts to the right and subtracting shifts to the left it seems
    
        //if ((checker & (1 << val)) > 0) return false;
        //This line is quite a mouthful, lets break it down:
        System.out.println(0<<0);
        //00000000000000000000000000000000
        System.out.println(0<<1);
        //00000000000000000000000000000000
        System.out.println(0<<2);
        //00000000000000000000000000000000
        System.out.println(0<<3);
        //00000000000000000000000000000000
        System.out.println(1<<0);
        //00000000000000000000000000000001
        System.out.println(1<<1);
        //00000000000000000000000000000010 == 2
        System.out.println(1<<2);
        //00000000000000000000000000000100 == 4
        System.out.println(1<<3);
        //00000000000000000000000000001000 == 8
        System.out.println(2<<0);
        //00000000000000000000000000000010 == 2
        System.out.println(2<<1);
        //00000000000000000000000000000100 == 4
        System.out.println(2<<2);
        // == 8
        System.out.println(2<<3);
        // == 16
        System.out.println("3<<0 == "+(3<<0));
        // != 4 why 3???
        System.out.println(3<<1);
        //00000000000000000000000000000011 == 3
        //shift left by 1
        //00000000000000000000000000000110 == 6
        System.out.println(3<<2);
        //00000000000000000000000000000011 == 3
        //shift left by 2
        //00000000000000000000000000001100 == 12
        System.out.println(3<<3);
        // 24
    
        //It seems that the -  'a' is not necessary
        //Back to if ((checker & (1 << val)) > 0) return false;
        //(1 << val means we simply shift 1 by the numeric representation of the current character
        //the bitwise & works as such:
        System.out.println();
        System.out.println();
        System.out.println(0&0);    //0
        System.out.println(0&1);       //0
        System.out.println(0&2);          //0
        System.out.println();
        System.out.println();
        System.out.println(1&0);    //0
        System.out.println(1&1);       //1
        System.out.println(1&2);          //0
        System.out.println(1&3);             //1
        System.out.println();
        System.out.println();
        System.out.println(2&0);    //0
        System.out.println(2&1);       //0   0010 & 0001 == 0000 = 0
        System.out.println(2&2);          //2  0010 & 0010 == 2
        System.out.println(2&3);             //2  0010 & 0011 = 0010 == 2
        System.out.println();
        System.out.println();
        System.out.println(3&0);    //0    0011 & 0000 == 0
        System.out.println(3&1);       //1  0011 & 0001 == 0001 == 1
        System.out.println(3&2);          //2  0011 & 0010 == 0010 == 2, 0&1 = 0 1&1 = 1
        System.out.println(3&3);             //3 why?? 3 == 0011 & 0011 == 3???
        System.out.println(9&11);   // should be... 1001 & 1011 == 1001 == 8+1 == 9?? yay!
    
        //so when we do (1 << val), we take 0001 and shift it by say, 97 for 'a', since any 'a' is also 97
    
        //why is it that the result of bitwise & is > 0 means its a dupe?
        //lets see..
    
        //0011 & 0011 is 0011 means its a dupe
        //0000 & 0011 is 0000 means no dupe
        //0010 & 0001 is 0011 means its no dupe
        //hmm
        //only when it is all 0000 means its no dupe
    
        //so moving on:
        //checker |= (1 << val)
        //the |= needs exploring:
    
        int x = 0;
        int y = 1;
        int z = 2;
        int a = 3;
        int b = 4;
        System.out.println("x|=1 "+(x|=1));  //1
        System.out.println(x|=1);     //1
        System.out.println(x|=1);      //1
        System.out.println(x|=1);       //1
        System.out.println(x|=1);       //1
        System.out.println(y|=1); // 0001 |= 0001 == ?? 1????
        System.out.println(y|=2); // ??? == 3 why??? 0001 |= 0010 == 3... hmm
        System.out.println(y);  //should be 3?? 
        System.out.println(y|=1); //already 3 so... 0011 |= 0001... maybe 0011 again? 3?
        System.out.println(y|=2); //0011 |= 0010..... hmm maybe.. 0011??? still 3? yup!
        System.out.println(y|=3); //0011 |= 0011, still 3
        System.out.println(y|=4);  //0011 |= 0100.. should be... 0111? so... 11? no its 7
        System.out.println(y|=5);  //so we're at 7 which is 0111, 0111 |= 0101 means 0111 still 7
        System.out.println(b|=9); //so 0100 |= 1001 is... seems like xor?? or just or i think, just or... so its 1101 so its 13? YAY!
    
        //so the |= is just a bitwise OR!
    }
    
    public static boolean isUniqueChars(String str) {
        int checker = 0;
        for (int i = 0; i < str.length(); ++i) {
            int val = str.charAt(i) - 'a';  //the - 'a' is just smoke and mirrors! not necessary!
            if ((checker & (1 << val)) > 0) return false;
            checker |= (1 << val);
        }
        return true;
    }
    
    public static boolean is_unique(String input)
    {
        int using_int_as_32_flags = 0;
        for (int i=0; i < input.length(); i++)
        {
            int numeric_representation_of_char_at_i = input.charAt(i);
            int using_0001_and_shifting_it_by_the_numeric_representation = 1 << numeric_representation_of_char_at_i; //here we shift the bitwise representation of 1 by the numeric val of the character
            int result_of_bitwise_and = using_int_as_32_flags & using_0001_and_shifting_it_by_the_numeric_representation;
            boolean already_bit_flagged = result_of_bitwise_and > 0;              //needs clarification why is it that the result of bitwise & is > 0 means its a dupe?
            if (already_bit_flagged)
                return false;
            using_int_as_32_flags |= using_0001_and_shifting_it_by_the_numeric_representation;
        }
        return true;
    }
    

提交回复
热议问题