Java binary translation? - java

I am trying to find some code that will easily break now a binary string. I'm not even sure I'm asking this question correctly, but I want to get the value of each "active bit". For example, if I have a binary string of 100000001, I would like to return the values 256, 1 in an array. I'm trying to figure this out so I can use a lookup table in SQL which has an integer column and a text column. The integer column will be used to determine which text values will be written to a new table. So, the value "Text1" at 1, and "Text 2" at 256 would both be written to the new table, but the number submitted to get those values would be 257.
I know I'm rambling, but I would input a value, 257, and I convert it to a binary string of 100000001. Now I want some code to break that binary string into two values... 1 and 256. Am I making any sense?

You don't need to convert to a binary string if you use Integer.highestOneBit. You can loop through the one bits, filling in an array of size Integer.bitCount with each call to Integer.highestOneBit. Afterwards, you can xor with the value of the highest bit to remove it from the number.
public static int[] getOneBits(int num) {
int[] oneBits = new int[Integer.bitCount(num)];
for (int i = 0; i < oneBits.length; i++) {
oneBits[i] = Integer.highestOneBit(num);
num ^= oneBits[i];
}
return oneBits;
}
Ideone Demo
This will produce an array, where all of the values are powers of 2 in descending order, where the sum of all the elements will be the original number. For example, 257 will produce [256, 1], and 127 will produce [64, 32, 16, 8, 4, 2, 1].

Related

Java Recursion to find MAX sum in array

I am trying to figure out a solution to calculate the highest sum of numbers in an array. However, my limitation is that I cannot use adjacent values in the array.
If I am given the array int [] blocks = new int[] {15, 3, 6, 17, 2, 1, 20}; the highest sum calculated is 52 (15+17+20).
My goal is to go from a recursive solution to a solution that uses dynamic programming, however, I am having trouble with the recursive solution.
The base cases that I have initialized:
if(array.length == 0)
return 0;
if(array.length == 1)
return array[0];
After creating the base cases, I am unsure of how to continue the recursive process.
I initially tried to say that if the array was of certain length, then I can calculate the max(Math.max) of the calculations:
e.g. if array.length = 3
return Math.max(array[0], array[1], array[2], array[0]+ array[2])
The problem I then run into is that I could be given an array of length 100.
How can I use recursion in this problem?
I think recursive solution to your problem is (in pseudocode):
maxsum(A,0) = 0
maxsum(A,1) = A[0]
maxsum(A,k) = max(maxsum(A,k-2)+A[k-1], maxsum(A,k-1)), for k >= 2
Where maxsum(A,k) means the maximal sum for a subarray of array A starting from 0 and having length k. I'm sure you'll easily translate that into Java, it translates almost literally.

(Java) Converting String of symbols to single digit integer array

I'm trying to take a String, i.e. $!#, convert each individual symbol to its corresponding ASCII value, it here being 36, 33, 35 and then ending up with an array of integers with each single number stored in a separate index, meaning 3, 6, 3, 3, 3, 5.
In short: From $!# to $,!,# to 36, 33, 35 to 3, 6, 3, 3, 3, 5
Since I am using Processing (wrapper for Java), my SO-research got me so far:
String str = "$!#";
byte[] b = str.getBytes();
for (int i=0; i<b.length; i++){
println(b[i]);
}
I'm ending up with the ASCII values. The byte array b contains [36, 33, 35].
Now if those were to be Strings instead of bytes, I would use String.valueOf(b) to get 363335 and then split the whole thing again into a single digit integer array.
I wonder if this approach is unnecessarily complicated and can be done with less conversion steps. Any suggestions?
Honestly, if I were you, I wouldn't worry too much about "efficiency" until you have an actual problem. Write code that you understand. If you have a problem with efficiency, you'll have to define exactly what you mean: is it taking too many steps? Is it taking too long? What is the size of your input?
Note that the approach you outlined and the approach below are both O(N), which is probably the best you're going to get.
If you have a specific bottleneck inside that O(N) then you should do some profiling to figure out where that is. But you shouldn't bother with micro-optimizations (or shudder premature optimizations) just because you "feel" like something is "inefficient".
To quote from this answer:
...in the absence of measured performance issues you shouldn't optimize because you think you will get a performance gain.
If I were you, I would just use the charAt() function to get each char in the String, and then use the int() function to convert that char into an int. Then you could add those int values to a String (or better yet, a StringBuilder):
String str = "$!#";
StringBuilder digits = new StringBuilder();
for (int i=0; i<str.length(); i++) {
int c = int(str.charAt(i));
digits.append(c);
}
Then you could use the split() function to split them into individual digits:
String[] digitArray = digits.toString().split("");
for (String d : digitArray) {
println(d);
}
Prints:
3
6
3
3
3
5
There are a ton of different ways to do this: you could use the toCharArray() function instead of charAt(), for example. But none of this is going to be any more or less "efficient" until you define exactly what you mean by efficiency.
Java 8 stream solution:
int[] digits = "$!#".chars()
.mapToObj(Integer::toString)
.flatMapToInt(CharSequence::chars)
.map(c -> c - '0')
.toArray();
System.out.println(Arrays.toString(digits)); // prints [3, 6, 3, 3, 3, 5]
One solution could be doing something like that
// Create an array of int of a size 3 * str.length()
for(int i = 0; i < str.length(); i++)
{
int n = (int) str.charAt(i);
int a = n / 100;
int b = (n - (a * 100)) / 10;
int c = n - (a * 100) - (b * 10);
// push a, b and c in your array (chose the order and if you want
// to add the potential 0's or not)
}
But as others said before, I'm not sure if it worth playing like that. It depends on your application I guess.

BitSet toString() and valueOf() are difficult to understand

I just want to convert integer to binary string using BitSet.
My code is below.
public class BitSetTest {
public static void main(String[] args) {
//Method_1
int value = 10; //0b1010
String bits = Integer.toBinaryString(value);
BitSet bs = new BitSet(bits.length());
for (int i = 0; i < bits.length(); i++) {
if (bits.charAt(i) == '1') {
bs.set(i);
} else {
bs.clear(i);
}
}
System.out.println(bs); //{0, 2} so 0th index and 2nd index are set.
System.out.println(Arrays.toString(bs.toLongArray())); //prints [5]
System.out.println(Arrays.toString(bs.toByteArray()));
//Method_2
value = 42;
System.out.println(Integer.toBinaryString(value)); //101010
BitSet bitSet = BitSet.valueOf(new long[] { value });
System.out.println(bitSet);
System.out.println(Arrays.toString(bitSet.toLongArray())); // prints [42]
System.out.println(Arrays.toString(bitSet.toByteArray()));
}
}
Q1) What i didn't understand; which is correct approach (Method_1 or Method_2).
Method_1 seems to be correct one, but bs.toLongArray() gives different results.
Q2) Could you please explain this api public static BitSet valueOf(long[] longs) accepts array of long values instead of single long ..? And what does really doing with this array.
Java doc says the below; but i really didn't get the meaning.
More precisely, BitSet.valueOf(longs).get(n) == ((longs[n/64] &
(1L<<(n%64))) != 0)
for all n < 64 * longs.length.
Please help.
Bits are numbered from the right.
42 = 0b101010
543210 <-- bit numbers
Hence output of {1, 3, 5}.
Your method #1 numbers bits from the left.
You also don't need to call bs.clear(i), since a new BitSet doesn't have any bits set.
All bits are initially false.
As for how BitSet.valueOf() works, it's fairly simple.
There are two versions for byte data (byte[], ByteBuffer), and two versions for long data (long[], LongBuffer).
A byte consists of 8 bits, and a long consists of 64 bits. The BitSet will then be built with the first N (8 or 64) bits from the first value, the next N bits from the second value, and so forth.
E.g. if you call BitSet.valueOf(new long[] { 1, 2, 3 }), bits 0-63 come from first number, bits 64-127 comes from second number, and bits 128-191 comes from third number, resulting in {0, 65, 128, 129}.
If you call BitSet.valueOf(new byte[] { 1, 2, 3 }), bits 0-7 come from first number, bits 8-15 comes from second number, and bits 16-23 comes from third number, resulting in {0, 9, 16, 17}.

Reverse Engineer Sorting Algorithm

I have been given 3 algorithms to reverse engineer and explain how they work, so far I have worked out that I have been given a quick sorting algorithm and a bubble sorting algorithm; however i'm not sure what algorithm this is. I understand how the quick sort and bubble sort work, but I just can't get my head around this algorithm. I'm unsure what the variables are and was hoping someone out there would be able to tell me whats going on here:
public static ArrayList<Integer> SortB(ArrayList<Integer> a)
{
ArrayList<Integer> array = CopyArray(a);
Integer[] zero = new Integer[a.size()];
Integer[] one = new Integer[a.size()];
int i,b;
Integer x,p;
//Change from 8 to 32 for whole integers - will run 4 times slower
for(b=0;b<8;++b)
{
int zc = 0;
int oc = 0;
for(i=0;i<array.size();++i)
{
x = array.get(i);
p = 1 << b;
if ((x & p) == 0)
{
zero[zc++] = array.get(i);
}
else
{
one[oc++] = array.get(i);
}
}
for(i=0;i<oc;++i) array.set(i,one[i]);
for(i=0;i<zc;++i) array.set(i+oc,zero[i]);
}
return(array);
}
This is a Radix Sort, limited to the least significant eight bits. It does not complete the sort unless you change the loop to go 32 times instead of 8.
Each iteration processes a single bit b. It prepares a mask called p by shifting 1 left b times. This produces a power of two - 1, 2, 4, 8, ..., or 1, 10, 100, 1000, 10000, ... in binary.
For each bit, the number of elements in the original array with bit b set to 1 and to 0 are separated into two buckets called one and zero. Once the separation is over, the elements are placed back into the original array, and the algorithm proceeds to the next iteration.
This implementation uses two times more storage than the size of the original array, and goes through the array a total of 16 times (64 times in the full version - once for reading and once for writing of data for each bit). The asymptotic complexity of the algorithm is linear.
Looks like a bit-by-bit radix sort to me, but it seems to be sorting backwards.

Generate a sequence of all permutation of some range of numbers

The following algorithm is given and we are supposed to write it out in java. However, when I try to understand line by line, it gets confusing, especially the part:
A[k+1:N-1] = the values in S in ascending order
To my understand, the set only have 1 number at anytime. How can we replace A[k+1:N-1] when the set only has 1 number?
Let A be a sequence of integers 0 to N-1 in ascending order (let's assume its an array of int[N]).
next_permutation(A):
k = N-1
S = { }
while k >= 0:
if S contains a value larger than A[k]:
v = the smallest member of S that is larger than A[k]
remove v from S
insert A[k] in S
A[k] = v
A[k+1:N-1] = the values in S in ascending order.
return true
else:
insert A[k] in S
k -= 1
return false
The algorithm shown is similar to the Generation in lexicographic order. You can read the article for further information.
#templatetypedef Any clue on how I can replace items in an array by values in a set in ascending order? e.g. A[k+1:N-1] = the values in S in ascending order. Should I use toArray()?
This is not needed. You can try to keep the S array sorted all the time. Every time you want to insert a new number in the array, you insert it in such, so the array could stay sorted.
For example, if you have S = [5 7 8] so far and you want to insert 6, you inserted between 5 and 7 - S = [5 6 7 8]. This way the replacement step is just copying the elements from S to A[k+1:N-1].

Categories