Can someone explain to my why this method works, I've worked through what it does, but why does this work. Is there a pattern that binary numbers have? Like for example at i = 3, why does it do res[1] + 1 to get 2. How does res[3 >> 1] + (3&1) help to count the number of ones in the binary number of 3?
What the code should do: It works so don't worry about that. It is supposed to return a list that contains the number of ones in the binary representation of each number until num+1. And num is always >= 0. So for num = 5, you would get [0, 1, 1, 2, 1, 2], where the last index represents the number of 1s in the binary representation of 5, and the first index is number of ones in binary rep of 0.
Code:
public int[] countBits(int num) {
int[] res = new int[num+1];
for (int i = 0; i<num+1; i++){
res[i] = res[i >> 1] + (i & 1);
}
return res;
}
This is the part I can't wrap my head around:
res[i] = res[i >> 1] + (i & 1);
EDIT - This is not homework, so please fully explain your answer. This is to help with interviews.
int[] res = new int[num+1];
for (int i = 0; i<num+1; i++){
res[i] = res[i >> 1] + (i & 1);
}
return res;
rewritten as
int[] res = new int[num+1];
for (int i = 0; i<num+1; i++){
x = res[i >> 1];
y = (i & 1);
res[i] = x + y;
}
return res;
Create an array to fit the answers, +1?
for each, starting at the low end.
res[0] = res[0] + 0&1 = 0 + 0 = 0;
res[1] = res[0] + 1&1 = 0 + 1 = 1;
res[2] = res[1] + 0&1 = 1 + 0 = 0;
res[3] = res[1] + 1&1 = 1 + 1 = 2;
Looking at this pattern, I can see that because of the right shift, and the masking with &, it's splitting the problem into 2, one that's been solved previously due to the iteration order, and a bit check of the last digit.
assuming a 8 bit int, for brevity,
1 = 00000001
2 = 00000010
3 = 00000011
Split the binary into parts.
i i>>1 y&1
1 = 0000000 1
2 = 0000001 0
3 = 0000001 1
So it fetches the results for the number of ones in the first half of the array, then counts the last digit.
Because of the iteration order, and array initialisation values, this is guaranteed to work.
For values < 0 , due to 2's compliment it gets hairy, which is why it only works for values >=0
in 'res[i] = res[i >> 1] + (i & 1);'
one number's result is divide into 2 parts
the last bit is 1 or not,which can be calculate by (i & 1).
the first (n-1) bits,this number is equals to res[i >> 1]'s bitcount.this is a simple recursive call
shift by 1 gives the floor number divided by 2.
AND 1 returns 1 if the last bit of the number is 1
Hope the below table helps to see what is happening :) Just my 2 cents.
<pre>
--------------------------------
<b>
# 8 4 2 1 >>1 &1 Ans
</b>
-------------------------------
0 0 0 0 0 0 0 0
1 0 0 0 1 0 1 1
2 0 0 1 0 1 0 1
3 0 0 1 1 1 1 2
4 0 1 0 0 2 0 1
5 0 1 0 1 2 1 2
6 0 1 1 0 3 0 2
7 0 1 1 1 3 1 3
8 1 0 0 0 4 0 1
9 1 0 0 1 4 1 2
10 1 0 1 0 5 0 2
11 1 0 1 1 5 1 3
12 1 1 0 0 6 0 2
13 1 1 0 1 6 1 3
14 1 1 1 0 7 0 3
15 1 1 1 1 7 1 4
</pre>
Related
I'm trying to create a pyramid that will double all the way to the center.
The code is producing this.
1
1 2 1
1 2 3 2 1
1 2 3 4 3 2 1
import java.util.Scanner;
for (i = 1; i<= lines; i++){ // sets rows (lines)
for (j = a; j >= 1; j--){ // dead space on left
System.out.printf(str," ");
}
for (k = 1; k != i; k++){ //left side numbers
String str1 = "" + k;
System.out.printf(str, str1);
}
a--;
for (int l = k; l >=1; l--){ // right side numbers
String str2 = "" + l;
System.out.printf(str, str2);
}
}
I expected it to look like this.
1
1 2 1
1 2 4 2 1
1 2 4 8 4 2 1
1 2 4 8 16 8 4 2 1
1 2 4 8 16 32 16 8 4 2 1
1 2 4 8 16 32 64 32 16 8 4 2 1
1 2 4 8 16 32 64 128 64 32 16 8 4 2 1
k and l should be used as exponents rather than as the numbers you are printing.
int lines = 8;
String str = "%4s"; //pads each number to 4 spaces
for (int i = 1; i <= lines; i++)
{
for (int j = 0; j < lines - i; j++) //Replaced a with lines - i
{
System.out.printf(str, " ");
}
for (int k = 1; k != i; k++)
{
//replaced k with 2 ^ (k - 1)
String str1 = "" + (int)(Math.pow(2, k - 1));
System.out.printf(str, str1);
}
for (int l = i; l >= 1; l--)
{
//replaced l with 2 ^ (l - 1)
String str2 = "" + (int)(Math.pow(2, l - 1));
System.out.printf(str, str2);
}
System.out.println(); //added newline between each line
}
Output:
1
1 2 1
1 2 4 2 1
1 2 4 8 4 2 1
1 2 4 8 16 8 4 2 1
1 2 4 8 16 32 16 8 4 2 1
1 2 4 8 16 32 64 32 16 8 4 2 1
1 2 4 8 16 32 64 128 64 32 16 8 4 2 1
Here is a solution that dynamically adjusts the spacing as needed.
The code uses <</>> bit-shifting to double/halve the numbers.
public static void printPyramidOfSquares(int lines) {
if (lines < 0 || lines > 63)
throw new IllegalArgumentException();
int width = Long.toString(1L << (lines - 1)).length();
for (int line = 1; line <= lines; line++) {
if (line < lines)
System.out.printf("%" + (lines - line) * (width + 1) + "s", "");
long val = 1;
for (int i = 1; i < line; i++, val <<= 1)
System.out.printf("%" + width + "d ", val);
for (int i = 1; i < line; i++, val >>= 1)
System.out.printf("%" + width + "d ", val);
System.out.printf("%" + width + "d%n", val);
}
}
Test
printPyramidOfSquares(4);
printPyramidOfSquares(5);
printPyramidOfSquares(8);
Output
1
1 2 1
1 2 4 2 1
1 2 4 8 4 2 1
1
1 2 1
1 2 4 2 1
1 2 4 8 4 2 1
1 2 4 8 16 8 4 2 1
1
1 2 1
1 2 4 2 1
1 2 4 8 4 2 1
1 2 4 8 16 8 4 2 1
1 2 4 8 16 32 16 8 4 2 1
1 2 4 8 16 32 64 32 16 8 4 2 1
1 2 4 8 16 32 64 128 64 32 16 8 4 2 1
Here is an alternative solution that calculates each row / col using the formula: "val = 2^(row - |lines - col - 1|)". It automatically adjusts the spacing using log base 10 to calculate the number of digits.
int s = 2 + (int) Math.log10(1 << lines);
IntStream.range(0, lines)
.mapToObj(r -> IntStream.range(0, 2 * lines - 1)
.map(c -> r - Math.abs(lines - c - 1))
.mapToObj(v -> v >= 0 ? String.format("%" + s + "d", 1 << v) : " ".repeat(s))
.collect(Collectors.joining()))
.forEach(System.out::println);
The wording of the problem is
"Write a method writeSequence that accepts an integer n as a parameter and prints a symmetric sequence of n numbers with descending integers ending in 1 followed by ascending integers beginning with 1, as in the table below:"
The table is essentially:
1 = 1
2 = 1 1
3 = 2 1 2
4 = 2 1 1 2
5 = 3 2 1 2 3
6 = 3 2 1 1 2 3
My attempted code is
public void writeSequence(int n){
if (n < 1){
throw new IllegalArgumentException();
}
if (n == 1){
System.out.print(n + " ");
}
else if (n == 2){
System.out.print(1 + " " + 1 + " ");
}
else if (n % 2 == 0){
System.out.print(n - (n/2) + " ");
writeSequence(n - (n/2));
System.out.print(n - (n/2) + " ");
}
else{
System.out.print(n-(n/2) + " ");
writeSequence(n - 2 );
System.out.print(n-(n/2)+ " ");
}
}
For inputs 1-10, my code is not generating the correct answer for 6, 8, and 10. Any help is greatly appreciated.
Edit:
Fixed spelling in title
Edit 2:
My results are
1 = 1
2 = 1 1
3 = 2 1 2
4 = 2 1 1 2
5 = 3 2 1 2 3
6 = 3 2 1 2 3 (wrong)
7 = 4 3 2 1 2 3 4
8 = 4 2 1 1 2 4 (wrong)
9 = 5 4 3 2 1 2 3 4 5
10 = 5 3 2 1 2 3 5 (wrong)
If someone could show me where I have made an error in my code that would be great!
Your recursive call passes the incorrect value. Each time the algorithm recurses, it should decrease the value by 2.
Change this:
writeSequence(n - (n/2));
to this:
writeSequence(n - 2);
I'm trying to generate a 8 by 8 matrix. Each element of matrix needs to have a value of 1 except one element on each column which is set as 0, that one element is chosen by generating a random int between 0-7.
What I get when I run the code:
1 1 1 1 1 1 1 1
1 1 1 0 1 1 1 1
1 1 0 1 1 1 1 1
1 0 1 1 1 1 1 1
1 0 1 1 1 1 1 1
1 0 0 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 0 1 1
My matrix should look like this:
1 1 1 1 1 1 1 1
1 1 0 1 1 1 1 1
1 1 1 1 1 0 1 0
0 1 1 1 1 1 1 1
1 1 1 0 1 1 0 1
1 0 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 0 1 1 1
code
for (int[] row: grid)
Arrays.fill(row, 1);
for (int i=0; i<grid.length; i++) {
int j = getRandom();
grid[i][j] = 0;
}
// print matrix
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++)
System.out.format("%2s%2d%2s", " ", Main.grid[i][j], " ");
System.out.println();
}
In your nested loop, both initialization and nulling of cells are in the innermost loop. This will cause both to run once per cell, but nulling is only done once per column.
If we change the order that the cells are initialized in from row after row to column after column, we can move the nulling logic out to the outermost loop.
for (int c = 0; c < 8; c++) {
for (int r = 0; r < 8; r++) {
Main.grid[r][c] = 1;
}
Main.grid[getRandom()][c] = 0; // assuming your getRandom() is within range
}
Firstly let's make the matrix all 1s:
//fill however you like
int[][] matrix = IntStream.range(0, 8).mapToObj(i
-> IntStream.range(0, 8).map(i -> 1).toArray());
Then, based on your question, it seems like you want a unique row per column to have a zero. So just shuffle your column indexes:
List<Integer> rows = IntStream.range(0, 8).collect(Collectors.toList());
Collections.shuffle(rows); //random rows per 0-8 column
AtomicInteger column = new AtomicInteger();
//iterate columns, and select random row
rows.forEach(i -> matrix[i][column.getAndIncrement()] = 0);
This'll disperse the random 0s to be unique per row (and column), and there's not really any RNG involved so it's O(n)
First of all, use the Arrays.fill api, it will make your code much cleaner and concise.
int[][] matrix = new int[m][n];
// Fill each row with 1
for (int[] row: matrix)
Arrays.fill(row, 1);
Then, for each row, pick a column number at random and insert '0' thereby replacing the 1.
for(int i=0; i<matrix.length; i++) {
int j = Math.Random(0,matrix[0].length); // Or any other api for random number generation
matrix[i][j] = 0;
}
Why HashMap insert new Node on the index:
tab[(n - 1) & hash]
Where hash = key.hashCode() ^ key.hashCode() >>> 16
And n = tab.length of array of Node<K,V>.
Why HashMap not put the Node just like that: tab[hash] ? Is it just another hashing function, like multiplication by 31 in most of hashCode() methods ?
Thanks in advance for explanation!
A good description by harold but I feel it is inadequate without an example. So heres one -
Whenever a new Hasmap is created the array size of internal Node[] table is always power of 2 and following method guarantees it -
static final int tableSizeFor(int cap) {
int n = cap - 1;
n |= n >>> 1;
n |= n >>> 2;
n |= n >>> 4;
n |= n >>> 8;
n |= n >>> 16;
return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
}
So lets say you provide initial capacity as 5
cap = 5
n = cap - 1 = 4 = 0 1 0 0
n |= n >>> 1; 0 1 0 0 | 0 0 1 0 = 0 1 1 0 = 6
n |= n >>> 2; 0 0 1 1 | 0 1 1 0 = 0 1 1 1 = 7
n |= n >>> 4; 0 0 0 0 | 0 1 1 1 = 0 1 1 1 = 7
n |= n >>> 8; 0 0 0 0 | 0 1 1 1 = 0 1 1 1 = 7
n |= n >>> 16; 0 0 0 0 | 0 1 1 1 = 0 1 1 1 = 7
return n + 1 7 + 1 = 8
So table size is 8 = 2^3
Now possible index values you can put your element in map are 0-7 since table size is 8. Now lets look at put method. It looks for bucket index as follows -
Node<K,V> p = tab[i = (n - 1) & hash];
where n is the array size. So n = 8. It is same as saying
Node<K,V> p = tab[i = hash % n];
So all we need to see now is how
hash % n == (n - 1) & hash
Lets again take an example. Lets say hash of a value is 10.
hash = 10
hash % n = 10 % 8 = 2
(n - 1) & hash = 7 & 10 = 0 1 1 1 & 1 0 1 0 = 0 0 1 0 = 2
Hope this helps. More details
PS: Above link goes to my blog that has a more details example explanation on this.
Because hash may be out of range.
The "canonical solution" is to take the (positive) modulo of the hash with the length of the array, this code uses the fact that the array has a power-of-two length to replace an expensive modulo by a variable (modulo a constant is optimized pretty well) with a cheap bitwise AND.
So I got this 2D Array that is a 5x5 array and I have to subtract or add 1 to one of the rows that the user chooses to change. All is fine when the user inputs to change the first row, but with the higher rows, for example 2, it adds more than 1.
The array values are
1 -2 1 0 0
-1 0 4 2 0
0 -4 1 -1 0
0 1 -1 -1 -2
0 -3 1 -1 0
And the method I used to add 1 is the following
public static void plusRow (int i){
for(int row = 0; row < board.length; row++){
int[] rows = board[i];
for(int col = 0; col < board.length; col++){
rows[col] = rows[col] + 1;
System.out.print(board[row][col] + " ");
}
System.out.println("");
}
}
My output value for example with 2 comes out like this
1 -2 1 0 0
1 2 6 4 2
0 -4 1 -1 0
0 1 -1 -1 -2
0 -3 1 -1 0
When it should be
1 -2 1 0 0
0 1 5 3 1
0 -4 1 -1 0
0 1 -1 -1 -2
0 -3 1 -1 0
The problem is that your nested for loop runs as many times as the function input int "i"
Your algorithm is very inefficient- you don't need to do a nested loop here. Break your ouput and your math into 2 different loops.
for(int j =0; j<boards[i].length; j++){
boards[i][j] += 1;
}
Then write a double loop to ouput board. In fact, that should be a separate function