what does this piece of code mean ...Can anyone explain how does this work..
sum += (i & (1<<j)) != 0 ? n[j] : 0;
full code:
int max = (1 << N)-1;
//System.err.println(max);
String res = "No";
for (int i = 0; i <= max; i++)
{
long sum = 0;
for (int j = 0; j < N; j++)
{
sum += (i & (1<<j)) != 0 ? n[j] : 0;
}
//System.err.println(i + " " + sum);
if(sum == m){
res = "Yes";
break;
}
Let's say that a = 0011 1100
So with the Binary Left Shift Operator (<<). The left operands value is moved left by the number of bits specified by the right operand.
A << 2 will give 240 which is 1111 0000
So in your code you have a loop for i and a loop for j
And this line
sum += (i & (1<<j)) != 0 ? n[j] : 0;
So for your second iteration of i = 2 and first iteration of j = 1
First the left shift operator will shift left all bits one position, resulting in 0000 0001 << 1 = 0000 0010 (or 2)
then you have a binary and comparison which will be i (0000 0010 in binary) & (0000 0010) = 0000 0010 (or 2)
And this and result will be asked if it's distinct of zero. If this result it's true then sum will be increased by the number in the n[j] array position, else will not be increased.
Java has a shortened version of an if else command. The use of it is very easy, once you understand it.
It’s written:
x ? y : z;
Here the question mark and the colon will take the place of the commands if and else.
This means:
condition ? inCaseOfTrue : elseCase;
With this code i & (1 << j) you get jth bit of i in binary representation. And if it equals 1 then you add n[j] to sum.
The full code shows you calculate all possible sums with selecting some elememts of array n;
Related
This question is related to but it is different in understanding how the code actually works. More precisely, I do not understand how numberOfTrailingZeros(int i) in java 8 here compute the final result. The code is as follows
public static int numberOfTrailingZeros(int i) {
// HD, Figure 5-14
int y;
if (i == 0) return 32;
int n = 31;
y = i <<16; if (y != 0) { n = n -16; i = y; }
y = i << 8; if (y != 0) { n = n - 8; i = y; }
y = i << 4; if (y != 0) { n = n - 4; i = y; }
y = i << 2; if (y != 0) { n = n - 2; i = y; }
return n - ((i << 1) >>> 31);
}
Now I understand the purpose of the shift operations from 16 to 2, but won't n have already the number of trailing zeros by the last shift operation:
y = i << 2; if (y != 0) { n = n - 2; i = y; }.
That is I do not understand the purpose of this particular line
n - ((i << 1) >>> 31);
why do we need that when n has already the right value?
Can anyone give a detailed example of what is going on?
Thanks!
I will try to explain the algorithm. It is a bit optimized, but I'll start with a (hopefully) more simplified approach.
It is used to determine the number of trailing zero bits of a 32 bit number, that is, how many zeros are on the right side (assuming most significant bit on left). The main idea is to divide the field in two half: if the right one is all zero we add the number of bits in the right half to the result and continue examining the left one (again dividing it); if the right one is not all zero, we can ignore the left one and continue examining the right one (adding nothing to the result).
Example: 0000 0000 0000 0010 0000 0000 0000 0000 (0x0002 0000)
first step (not java code, all numbers base 2, result is decimal):
i = 0000 0000 0000 0010 0000 0000 0000 0000
left = 0000 0000 0000 0010
right = 0000 0000 0000 0000
result = 0
since right is zero, we add 16 (actual number of bits in right part) to the result and continue examining the left part
second step:
i = 0000 0000 0000 0010 // left from previous
left = 0000 0000
right = 0000 0010
result = 16
now right is not zero, so we add nothing to result and continue with right part
third step:
i = 0000 0010 // right from previous
left = 0000
right = 0010
result = 16
right is not zero, nothing added to result, continue with right part
4th step:
i = 0010 // right from previous
left = 00
right = 10
result = 16
5th step:
i = 10 // right from previous
left = 1
right = 0
result = 16
now right is zero, so we add 1 (number of bits in right part) and there is nothing else to divide (that is the return line off original code)
result = 17
Optimizations: instead of having the left and the right part, the algorithm only examines the left left x-most bits of the number and just shift the right part into the left if the right one is not zero, example for first step:
y = i << 16; if (y != 0) { ... i = y;}
and, to avoid having an else part (I think), it starts the result with 31 (sum of all part lengths 1+2+4+8+16) and subtracts the bit count if the right side (after shifting the now left one) is not zero. Again for the first step:
y = i << 16; if (y != 0) { n = n - 16; ....}
Second optimization, last step, instead of
y = i << 1; if (y != 0) { n = n - 1; /* i = y not needed since we are done*/ }
return n;
it does just
return n - ((i << 1) >>> 31);
here ((i << 1) >>>31) is shifting the second bit (second leftmost, second highest bit) of i to leftmost position (eliminating the first bit) and then shifting it to rightmost position, that is, resulting in 0 if the second bit is zero, 1 otherwise. Which is then subtracted from the result (to undo the sum 31 from the beginning).
The first (leftmost) bit need not be directly examined. It only matters if all other bits are zero, that is, the number is 0, checked at the very beginning (if (i == 0) return 32;) or it is -1 in which case the initial value of result is returned: 31.
There is a changing rule that, 0 -> 01, 1 -> 10. For example, after the change, 10 is 1001.
Assume that the input is 0, after n changes of such rule, what is the Kth digit?
I can only come with the brutal solution, which is as followings. However I believe there exist better solutions, can anyone come up with some new ideas?
public char lalala(int n, int k) {
String str = "0";
for (int i = 0; i < n; i++) {
StringBuilder sb = new StringBuilder();
for (int j = 0; j < str.length; j++) {
if (str.charAt(j) == '0') {
sb.append("01");
} else {
sb.append("10");
}
}
str = sb.toString();
}
return str.charAt(k);
}
So your generated string will look like
0110100110010110....
Now lets write this numbers vertically and lets print binary representation of position of each digit
value|position -> position binary
-----+---------------------------
0 | 0 -> 0000
1 | 1 -> 0001
1 | 2 -> 0010
0 | 3 -> 0011
1 | 4 -> 0100
0 | 5 -> 0101
0 | 6 -> 0110
1 | 7 -> 0111
. . ....
. . ....
If you take closer look you will see that:
if number of 1 in binary representation of position is even value is 0
if number of 1 in binary representation of position is odd value is 1
which means that
0001, 0010, 0100, 0111 contains odd number of 1 value will be 1.
In other words value is equal of number of ones modulo 2.
Using this fact you can create code which will convert your n to string representing its binary form, sum all ones, and check if it is odd or even.
Code converting n to value can look like this
public static int value(int n) {
String binary = Integer.toBinaryString(n);
return binary.chars().map(e -> e == '1' ? 1 : 0).sum() % 2;
}
(little longer version if you are not familiar with streams introduced in Java 8)
public static int value(Integer n) {
String binary = Integer.toBinaryString(n);
int count = 0;
for (char ch : binary.toCharArray())
if (ch == '1') count ++;
return count % 2;
}
and when you use it like
for (int i = 0; i < 20; i++)
System.out.print(value(i));
you will get as output 01101001100101101001 which seems correct.
I have a Java CRC16 function like below and I need it to return a 4 length alphanumeric result. But sometimes it returns only a 3 length alphanumeric. Why? I am cross comparing this CRC with a C application that calculates the CRC and usually it is the same CRC but from time to time the JAVA returns a 3 character result which raises an exception. Why?
int crrc = 0xFFFF; // initial value
int polynomial = 0x1021; // 0001 0000 0010 0001 (0, 5, 12)
String str = "0009";
byte []by = x; // x is the byte array from args
for (byte b : by) {
for (int i = 0; i < 8; i++) {
boolean bit = ((b >> (7-i) & 1) == 1);
boolean c15 = ((crrc >> 15 & 1) == 1);
crrc <<= 1;
if (c15 ^ bit) crrc ^= polynomial;
}
}
crrc &= 0xffff;
System.out.println(crrc);
System.out.println("CRC16-CCITT = " + Integer.toHexString(crrc) + " " + Integer.toHexString(crrc).length());
You're receiving ArrayIndexOutOfBoundException probably, so I think the hex value might have zero in its most significant nibble. Try to find out those values(x) and check whether (x >>> 12) == 0 or (x & 0xf000) == 0. If this returns true, you can pad your string with necessary number of 0s from the left.
One possible way: String.format("%04d", crrc)
How to find the next lower binary number for an integer (same number of 1s)? For example: if given input number n = 10 (1010), the function should return 9 (1001), or n = 14 (1110) then return 13 (1101), or n = 22 (10110) then return 21 (10101), n = 25 (11001) then return 22 (10110)... etc.
You can do this.
static int nextLower(int n) {
int bc = Integer.bitCount(n);
for (int i = n - 1; i > 0; i--)
if (Integer.bitCount(i) == bc)
return i;
throw new RuntimeException(n+" is the lowest with a bit count of "+bc);
}
Of course if this is homework you are going to have trouble convincing someone you wrote this ;)
For the sake of clarity, in this answer I will use the term 'cardinality' to indicate the number of 1s in the binary representation of a number.
One (obvious) way is to run a downwards loop, and seek for the first number with the same cardinality as your input (just like Peter Lawrey suggested).
I don't think this is inefficient, because I guess the output number is always pretty close to the input. More precisely, all you have to do is to find the rightmost '10' bit sequence, and change it to '01'. Then replace the right part with a number having all 1s at its left, as many as you can, without breaking the postcondition. This brings us to another solution, which consists in converting the number to a binary string (like user2573153 showed you), performing the replacement (with a regular expression, maybe), and then converting back to int.
A slightly faster version of Peter's algorithm should be the following, which performs on integers the manipulation I proposed you for strings:
static int nextLower(int n) {
int fixPart = 0;
int shiftCount = 0;
while ((n & 3) != 2) {
if (n == 0) {
throw new IllegalArgumentException(
fixPart + " is the lowest number with its cardinality");
}
fixPart |= (n & 1) << shiftCount;
shiftCount += 1;
n /= 2;
}
int fixZeros = shiftCount - Integer.bitCount(fixPart);
return ((n ^ 3) << shiftCount) | (((1 << shiftCount) - 1) & ~((1 << fixZeros) - 1));
}
which is O(log n) rather than O(n), but it's definitely harder to understand, and may also be practically slower, due to its complexity. Anyway, you could only notice a difference if you try with some huge difficult number.
EDIT I tried a little benchmark, and found that this code is 67% faster than Peter Lawrey's when applied consecutively to all numbers from 2 to 100,000,000. I don't think this is enough to justify the increased code complexity.
I like such binary task, so to find next lower number you should find right most 1 followed by 0 and exchange them,. UPDATE: you need to "reorder" the rest part of number with 1s at left and 0s at right
10 1010 ->
9 1001
14 1110 ->
13 1101
25 11001 ->
22 10110
here is sample code:
int originalValue = 25;
int maskToCheck = 2; // in binary 10b
int clearingMask = 1;
int settingMask = 0;
int zeroCount = 0;
while (maskToCheck > 0)
{
if ( (originalValue&(maskToCheck|(maskToCheck>>1))) == maskToCheck ) // we found such
{
int newValue = originalValue&(~maskToCheck); // set 1 with 0
newValue = newValue&(~clearingMask)|(settingMask<<zeroCount); // clear all the rest bits, and set most valuable ones
newValue = newValue|(maskToCheck>>1); // set 0 with 1
System.out.println("for " + originalValue + " we found " + newValue);
break;
}
else
{
if ( (originalValue&(maskToCheck>>1)) > 0) // we have 1 bit in cleared part
settingMask = (settingMask<<1) | 1;
else
zeroCount++;
maskToCheck = maskToCheck<<1; // try next left bits
clearingMask = (clearingMask<<1)|1;
}
}
I am trying to write a algorithm that will print a powerset of a given set of numbers. I did that with a loop that goes from zero to 2^length of my set. I convert the index i to binary, and whenever there is a one, I print that number. However, since the string does not have any preceding zeros, I am not getting the right output.
For example, if I have a set of three numbers: {2, 3, 4}, when i is 3, I want the string to be "011", but instead it is "11" and I'm getting an output of 2, 3 instead of 3, 4.
Here is my code:
public static void powerset (int[] A){
double powerSetLength = Math.pow(2, A.length);
for (int i=0; i<powerSetLength; i++){
String bin = Integer.toBinaryString(i);
System.out.println ("\nbin: " + bin);
for (int j=0; j<bin.length(); j++){
if (bin.charAt(j)=='1')
System.out.print(A[j] + " ");
}
}
System.out.println();
}
Here is the output that I am getting:
9 7 2
bin: 0
bin: 1
9
bin: 10
9
bin: 11
9 7
bin: 100
9
bin: 101
9 2
bin: 110
9 7
bin: 111
9 7 2
Here is an example of the output that I would like to get:
9 7 2
bin 001
2
I would like to know if there is a way to convert an integer to binary with a specified number of bits so that I can get this output.
One easy way to deal with this problem is assuming that if a digit is missing in the representation, then its value is zero. You can do it like this:
// The number of digits you want is A.length
for (int j=0; j < A.length ; j++) {
// If j is above length, it's the same as if bin[j] were zero
if (j < b.length() && bin.charAt(j)=='1')
System.out.print(A[j] + " ");
}
}
Of course if you can assume that A.length < 64 (which you should be able to assume if you want your program to finish printing in under a year) you could use long to represent your number, and bit operations to check if a bit is set or not:
int len = A.length;
for (long mask = 0 ; mask != (1L << len) ; mask++) {
for (int i = 0 ; i != len ; i++) {
if ((mask & (1L << i)) != 0) {
System.out.print(A[j] + " ");
}
}
System.out.print();
}
String padded = String.format("%03d", somenumber);
or
System.out.printf("%03d", somenumber);
Would each pad to three digits (the 3 in the format specifier). You could additionally build the specifier programatically based on length you need:
String.format("%0" + n + "d", somenumber)
But this is unnecessary if you just need to know if bit N is set. You could just as easily do this:
if ((value & (1L << n)) != 0) { }
Where value is the number, and n is the ordinal of the bit you want. This logically ands the bit in question with the value - if it's set, the result is non-zero, and the if is true. If it is not set, the result is zero, and the if is false.