Cpunit Ii
Cpunit Ii
SYLLABUS
Applications:
1. Introduction
2. Counting Bits
3. Palindrome Permutation
4. Remove All Ones with Row and Column Flips
5. Encode Number.
Introduction
Usually a signed representation is used, which means that both negative and
– positive numbers can be represented.
A signed variable of n bits can contain any integer between 2n−1 and2n−1 -1. For
example, the int type in Java is a signed type, so an int variable can contain any integer
between -231 and 231 -1.
The first bit in a signed representation is the sign o− f the number (0 for nonnegative
numbers and 1 for negative numbers), and the remaining n 1 bits contain the magnitude of
the number.
Two’s complement is used, which means that the opposite number of a number is
calculated by first inverting all the bits in the number and then increasing the number
by one. For example, the bit representation of the number −43 is
11111111111111111111111111010101.
If a number is larger than the upper bound of the bit representation, the number will
overflow.
In a signed representation, the next number after 2n−1 − 1 is −2n−1.
Initially, the value of x is 231 − 1. This is the largest value that can be stored in an
int variable, so the next number after 231 − 1 is −231.
Bit Operations
And Operation The and operation x & y produces a number that has one bits in
positions where both x and y have one bits. For example, 22 & 26 = 18, because
10110 (22)
Or Operation The or operation x | y produces a number that has one bits in positions
where at least one of x and y have one bits. For example, 22 | 26 = 30, because
KESHAV MEMORIAL INSTITUTE OF TECHNOLOGY (AN AUTONOMOUS INSTITUTE)
COMPETITIVE PROGRAMMING UNIT-II III-II SEM (KR21 Regulations)
10110 (22)
| 11010 (26)
= 11110 (30).
Xor Operation The xor operation x ˆ y produces a number that has one bits in
positions where exactly one of x and y have one bits. For example, 22 ˆ 26=12,
because
10110 (22)
ˆ 11010 (26)
= 01100 (12).
Not Operation: The not operation ~x produces a number where all the bits of x have
been inverted. For example, ~29 is 30. The resultof the not operation at the bit level
depends on the length of the bit representation, because the operation inverts all
bits. For example, if the numbers are 32-bit integers, the result is as follows:
x = 29 -> 00000000000000000000000000011101
~
x = −30 -> 11111111111111111111111111100010
Bit Shifts: The left bit shift x << k appends k zero bits to the number, and the right bit shift
x >> k removes the k last bits from the number. For example, 14<<2=56 , because 14 and
56 correspond to 1110 and 111000. Similarly, 49 >> 3 is 6, because 49
and 6 correspond to 110001 and 110.
Bit manipulation is the process of applying logical operations on a sequence of bits, the
smallest form of data in a computer, to achieve a required result. Bit manipulation has
constant time complexity and process in parallel, meaning it is very efficient on all systems.
Most programming languages will have you work with abstractions, like objects or variables,
rather than the bits they represent. However, direct bit manipulation is needed to improve
performance and reduce error in certain situations.
For example, take a look at the difference between an arithmetic and bit manipulation
approach to finding the green portion of an RGB value:
// arithmetic
(rgb / 256) % 256
// bit
(rgb >> 8) & 0xFF
While both do the same thing, the second option is considerably faster, as it works directly
within memory rather than through a level of abstraction.
We’ll explore what each of these operators do later in this article (>> and &).
Bitwise Operators:
Bitwise operations take one or more bit patterns or binary numerals and manipulate them at
the bit level. They’re essentially our tool to manipulate bits to achieve our operations.
Advantages
AND (&) is a binary operator that compares two operands of equal length. The operands are
converted from their readable form to binary representation. For each bit, the operation
checks if both bits are 1 across both operands. If yes, that bit is set to 1 in the answer.
Otherwise, the corresponding result bit is set to 0.
It essentially multiplies each bit by the corresponding bit in the other operand. As multiplying
anything by 0 results in 0, the AND comparison with any 0 bit will result in 0.
0101 (decimal 5)
AND 0011 (decimal 3)
0∗0=00∗0=0
1∗0=01∗0=0
0∗1=00∗1=0
1∗1=11∗1=1
Therefore:
= 0001 (decimal 1)
Example:
class AndOperation
{
public static void main( String args[] )
{
int x = 12;
int y = 10;
System.out.println("Bitwise AND of (" + x + " , " + y + ") is: " + (x & y)); // yields to 8
}
2. Bitwise OR( | ):
The OR operator (|) is a binary operator that takes two equal-length operands but compares
them in the opposite way to AND; if either corresponding bit is 1, the answer is 1. Otherwise,
the answer will be 0. In other words, Bitwise OR returns ‘1’ if one of the inputs given is 1.
a = 12
b = 10
---------------------------------
a in Binary : 0000 0000 0000 1100
b in Binary : 0000 0000 0000 1010
---------------------------------
a|b : 0000 0000 0000 1110
---------------------------------
This is often used as an interim logic step for solving other problems.
Example:
class OROperation
{
private static int helper(int x, int y) {
return x | y;
}
public static void main(String[] args) {
int x = 12;
int y = 10;
System.out.println("Bitwise OR of " + x + ", " + y + " is: " + helper(x, y)); // yields to 14
}
Output:
NOT (~), or sometimes called the bitwise complement operator, is a unary operation that
takes a single input and swaps each bit in its binary representation to the opposite value.
All instances of 0 become 1, and all instances of 1 become 0. In other words, NOT inverts
each input bit. This inverted sequence is called the one’s complement of a bit series.
This makes the number negative as any bit collection that starts with 1 is negative.
NOT is useful for flipping unsigned numbers to the mirrored value on the opposite side of
their mid point.
Formula: x=232–x
Example:
class NOTOperation
{
public static void main( String args[] )
{
int a = 1;
System.out.println("Bitwise NOT of a is : " + ~a);
}
Output:
Bitwise NOT of a is : -2
The bitwise XOR operation (^), short for “Exclusive-Or”, is a binary operator that takes two
input arguments and compares each corresponding bit. If the bits are opposite, the result
has a 1 in that bit position. If they match, a 0 is returned.
1 ^ 1 => yields to 0.
0 ^ 0 => yields to 0.
1 ^ 0 => yields to 1.
0 ^ 1 => yields to 1.
For example:
a = 12
b = 10
---------------------------------
a in binary : 0000 0000 0000 1100
b in binary : 0000 0000 0000 1010
---------------------------------
a^b : 0000 0000 0000 0110
---------------------------------
XOR is also sometimes used to set the value of a registry to zero as XOR with two of the
same input will always result in 0.
Example:
class XOROperation
{
public static void main( String args[] )
{
int x = 12;
int y = 10;
System.out.println("Bitwise XOR of (x , y) is : " + (x ^ y)); // yields to 6
}
} Output:Bitwise XOR of (x , y) is : 6
Below is a table showing a comparison of results of all the bitwise operators mentioned above
based on different values of the compared bits (A and B).
A bit shift is a Bitwise operation where the order of a series of bits is moved to efficiently
perform a mathematical operation. A bit shift moves each digit in a number’s binary
representation left or right by a number of spaces specified by the second operand.
These operators can be applied to integral types such as int, long, short, byte, or char.
Left shift: << is the left shift operator and meets both logical and arithmetic shifts’
needs.
Arithmetic/signed right shift: >> is the arithmetic (or signed) right shift operator.
In Java, all integer data types are signed and << and >> are solely arithmetic shifts.
Shifting this bit pattern to the left one position (6 << 1) results in the number 12:
As you can see, the digits have shifted to the left by one position, and the last digit on the
right is filled with a zero. Note that shifting left is equivalent to multiplication by powers
of 2.
Well-optimized compilers will use this rule to replace multiplication with shifts whenever
possible, as shifts are faster.
Example:
class LeftShift
{
private static int helper(int number, int i)
{
return number << i;// multiplies `number` with 2^i times.
}
public static void main(String[] args)
{
int number = 100;
System.out.println(number + " shifted 1 position left, yields to " + helper(number, 1));
System.out.println(number + " shifted 2 positions left, yields to " + helper(number, 2));
System.out.println(number + " shifted 3 positions left, yields to " + helper(number, 3));
System.out.println(number + " shifted 4 positions left, yields to " + helper(number, 4));
}
KESHAV MEMORIAL INSTITUTE OF TECHNOLOGY (AN AUTONOMOUS INSTITUTE)
COMPETITIVE PROGRAMMING UNIT-II III-II SEM (KR21 Regulations)
}
Output:
100 shifted 1 position left, yields to 200
100 shifted 2 positions left, yields to 400
100 shifted 3 positions left, yields to 800
100 shifted 4 positions left, yields to 1600
With right shift, you can either do arithmetic (>>) or logical (>>) shift.
The difference is that arithmetic shifts maintain the same most significant bit (MSB) or sign
bit, the leftmost bit which determines if a number is positive or negative.
On the other hand, a logical shift simply moves everything to the right and replaces the MSB
with a 0.
10110101>>>1= 01011010
Example:
class RightShift
{
public static void main(String[] args)
{
int number1 = 8;
int number2 = -8;
Output:
2
-2
(x & 1 ) == 0
0110 (6)
& 0001
= 0000 TRUE
2 equates to 0001
The rightmost number for all odd numbers greater than 2 is 1
Any time the final bit evaluates to 1, you know that it matched and is, therefore, an odd
number. If it instead evaluates to 0, you know that no numbers matched and therefore it’s
even.
Output:
True
2. Using X-OR: Write a java progam for Convert characters to uppercase or lowercase
This trick tests your knowledge of uppercase and lowercase characters in binary. You
can convert any character, ch, to the opposite case using ch ^= 32.
This is because the binary representation of lowercase and uppercase letters are nearly
identical, with only 1 bit of difference.
Using the XOR operation lets us toggle that single bit and swap it to the opposite
value, therefore making a lowercase character uppercase or vice versa.
Program:
// tOGGLE cASE = swaps CAPS to lower case and lower case to CAPS
static String toggleCase(char[] a)
{
for (int i=0; i<a.length; i++) {
Output:
3. Using Bitwise AND: Write a Java program to count the number of bits set to 1 (set
bits) of an integer.
If a number has 2 set bits, then the while loop runs two times.
If a number has 4 set bits, then the while loop runs four times.
Our while loop iterates until n = 0, dividing by 2 each time via the AND operator. On pass
1, 125 becomes 62, and count increases by 1. On the second pass, 62 becomes 31, and the
count increases to 2. This continues until n becomes 0 and the count is then returned.
Program:
class CountSetBit
{
private static int helper(int n)
{
int count = 0;
while (n > 0)
{
n &= (n - 1);
count++;
}
return count;
}
Output:
SetBit Count is : 6
4. Using Bitwise OR: Number of Flips: Write a program that takes 3 integers and uses
the lowest number of flips to make the sum of the first two numbers equal to the third.
The program will return the number of flips required.
A flip is changing one single bit to the opposite value ie. 1 --> 0 or 0 --> 1.
Input: a = 2, b = 6, c = 5
Output: 3
Explanation:
Program:
class MinFlips
{
private static int helper(int a, int b, int c) {
int ans = 0;
for (int i = 0; i < 32; i++) {
int bitC = ((c >> i) & 1);
int bitA = ((a >> i) & 1);
int bitB = ((b >> i) & 1);
5. Using Bitwise XOR: Single Number- Find the element in an array that is not
repeated.
Input: nums = { 4, 1, 2, 9, 1, 4, 2 }
Output: 9
If we take XOR of zero and some bit, it will return that bit: a ^ 0 = a
If we take XOR of two same bits, it will return 0: a ^ a = 0
For n numbers, the below math can be applied: a ^ b ^ a = (a ^ a) ^ b = 0 ^ b = b
For example,
1^5^1=
(11)5=
05=5
Therefore, we can XOR all bits together to find the unique number.
Program:
class SingleNumber
{
private static int singleNumber(int[] nums)
{
int xor = 0;
for (int num : nums) {
xor ^= num;
}
return xor;
}
public static void main(String[] args) {
int[] nums = {4, 1, 2, 9, 1, 4, 2};
System.out.println("Element appearing one time is " + singleNumber(nums));
}
}
Output:
Element appearing one time is 9
6. Using Bitwise Left Shift: Get First Set BitGiven an integer, find the position of the
first set-bit (1) from the right.
Input: n = 18
18 in binary = 0b10010
Output: 2
Procedure:
The logic of this solution relies on a combination of left shifting and the AND operation.
Essentially, we first check if the rightmost significant bit is the set bet using bit & 1. If not,
we keep shifting left and checking until we find the bit that makes our AND operation yield 1.
The number of shifts is tracked by our pointer, k. Once we do find the set bit, we return k as
our answer.
Program
class FirstSetBitPosition
{
private static int helper(int n)
{
if (n == 0)
{
return 0;
}
int k = 1;
while (true)
{
if ((n & (1 << (k - 1))) == 0)
{
k++;
} else {
return k;
}
}
}
Output:
First setbit position for number: 18 is -> 2
First setbit position for number: 5 is -> 1
First setbit position for number: 32 is -> 6
input=
Enter the first number: 7
Enter the second number: 9
output=
Before swapping:
79
After swapping:
97
Complexity Analysis
1. Counting Bits
Given an integer n, return an array ans of length n + 1 such that for each i (0 <= i <= n),
ans[i] is the number of 1's in the binary representation of i.
Input: n = 2
Output: [0,1,1] Explanation:
0 --> 0
1 --> 1
2 --> 10
Input: n = 5
Output: [0,1,1,2,1,2]
Explanation:
0 --> 0
1 --> 1
2 --> 10
3 --> 11
4 --> 100
5 --> 101
Procedure:
1. Since for decimal number 0 , no. of '1' bits in its binary representation = 0
2. For each value from 1 loop to iterate each bit of the number and count no. of '1' bits till
the number becomes 0 i.e.it has no '1' bits remaining in its binary representation.
3. 0 will be added to count if last bit is 0 , and 1 will be added to count variable if last bit is
1, there by increasing count to 1.
4. Drop the last bit and repeat the process of counting the 1 bits.
Write a Java Program to count the number of 1 in bit representation from 0 to a given
value
CountingBits.java
import java.util.*;
class CountingBits
{
public static int[] countBits(int n)
{
int r[]= new int[n+1]; r[0]=0;
for(int i=1; i<=n; i++)
{
int ct=0; int x=i; while(x>0)
{
ct+= (x & 1); x= x >> 1;
}
r[i]= ct;
}
return r;
}
public static void main(String[] args)
{
Scanner s=new Scanner(System.in);
int n=s.nextInt();
int r[]=new int[n+1];
r=countBits(n);
for(int i=0;i<=n;i++)
System.out.println(" "+r[i]);
}
}
2. Palindrome Permutation
Example 1:
Input: "code"
Output: false
Example 2:
Input: "aab"
Output: true
Example 3:
Input: "carerac"
Output: true
If a string with an even length is a palindrome, every character in the string must always
occur even number of times. If the string with an odd length is a palindrome, every character
except one of the characters must occur even number of times. Thus, in case of a
palindrome, the number of characters with odd number of occurrences can't exceed 1 (1 in
case of odd length and 0 in case of even length).
Procedure:
PermutePalindrome.java
import java.util.*;
class PermutePalindrome
{
static boolean canPermutePalindrome(String s)
{
int bitmask = 0;
for(int i=0;i<s.length();i++)
{
char ch=s.charAt(i);
bitmask ^= (1 << (ch - 'a'));
}
return (bitmask == 0 || (bitmask & (bitmask-1)) == 0 );
}
public static void main(String[] args)
{
Scanner s=new Scanner(System.in);
System.out.println(“Enter the string”);
String ps=s.next();
System.out.println(canPermutePalindrome(ps));
}
}
In one operation, you can choose any row or column and flip each value in that row or column
(i.e., changing all 0's to 1's, and all 1's to 0's).
Return true if it is possible to remove all 1’s from the grid using any number of operations or false
otherwise.
Procedure:
Write a Java Program to determine whether it is possible to remove all 1’s from a
binary matrix with row and column flips.
RemoveAllOneswithFlips.java
import java.util.*;
class RemoveAllOneswithFlips
{
public static boolean removeOnes(int grid[][])
{
//every row should be equal to first row or complement to first row
//or else there will always be an extra value
//if the matrix only has one row then it is always true
if (rows <= 1) return true;
return revRow;
}
public static void main(String[] args)
{
Scanner s=new Scanner(System.in);
System.out.println("Enter square matrix order");
int n=s.nextInt();
int grid[][]=new int[n][n];
System.out.println("Enter the binary matrix");
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
grid[i][j]=s.nextInt();
}
}
KESHAV MEMORIAL INSTITUTE OF TECHNOLOGY (AN AUTONOMOUS INSTITUTE)
COMPETITIVE PROGRAMMING UNIT-II III-II SEM (KR21 Regulations)
System.out.println(removeOnes(grid));
}
}
(OR)
import java.util.*;
class RemoveAllOneswithFlips
{
public boolean removeOnes(int[][] grid)
{
int row = grid.length; // get dimensions of grid
int col = grid[0].length;
}
return true;
}
4. Encode Number
The encoding is done by converting the integer to a string using a secret function that you
should deduce from the following table:
N f(n)
0 “”
1 “0”
2 “1”
3 “00”
4 “01”
5 “10”
6 “11”
7 “000”
Example 1:
Input: num = 23
Output: “1000”
Example 2:
Input: num = 107
Output: “101100”
If n is 0, then f(n) is "". If 1 <= n < 3, then f(n) is a binary string with length 1. If 3
<= n < 7, then f(n) is a binary string with length 2. If 7 <= n < 15, then `f(n) is a binary
string with length 3.
Procedure
1. For the given number num, obtain the number of bits bits for number num + 1, where the
number of bits means the number of bits remaining after removing leading zeros.
2. Calculate difference as the difference between num + 1 and 2 ^ bits, and return the
binary representation of difference.
EncodeNumber.java
import java.util.*;
class EncodeNumber
{
public static String encode(int num)
{
num++;
int bits = (int) (Math.log(num) / Math.log(2));
System.out.println(bits);
int difference = num - (int) Math.pow(2, bits);
String encodeStr = binary(difference, bits);
return encodeStr;
}