I have a character array consisting of the elements b and r arranged as {'b','b','r','r','b','r'};
What I want to find is the maximum number of those two characters without an interruption in their arrangement.
Example:
ar = {'b','b','r','r','b','r'};
The output should be 4 because bb rr each contains two characters and there is no mixing of b with rr or r with bb.
This is what I came up with :
int i =0;
int max=0;
while(i<ar.length){
char c = ar[i];
int count = 0;
while(i<ar.length&&ar[i] ==c){i++;count++;}
if(i==ar.length)break;
char n_c = ar[i];
while(i<ar.length && ar[i]==n_c){i++;count++;}
if(i==ar.length) break;
if(count>max) max=count;
}
If you want to find the maximum sub array length which contains only continious r and b, here is a solution. The basic idea is using two cursor and greedy search.
public static int findMaximum(char[] input) {
int result = 0;
int first = 0;
int second = 0;
while (input[first] == input[second]) {
second++; // the second index should start from another character
}
while (second < input.length) {
int preSecond = second; // copy second, in need reset first to it
while (second + 1 < input.length && input[second] == input[second + 1]) {
second++; // increment second
}
result = Math.max(result, second - first + 1);
if (second < input.length - 1) {
first = preSecond;
}
second++;
}
return result;
}
some test cases:
public static void main(String[] args) {
System.out.println(findMaximum(new char[]{'b','b','r'})); //3
System.out.println(findMaximum(new char[]{'b','b','r','r'})); //4
System.out.println(findMaximum(new char[]{'b','b','r','r','r','b','r'})); //5
System.out.println(findMaximum(new char[]{'b','b','b','r','r','b','r'})); //5
System.out.println(findMaximum(new char[]{'b','b','r','r','b','r','r','r','r','r'})); //6
}
In Java, having a number like 0b1010, I would like to get a list of numbers "composing" this one: 0b1000 and 0b0010 in this example: one number for each bit set.
I'm not sure about the best solution to get it. Do you have any clue ?
Use a BitSet!
long x = 0b101011;
BitSet bs = BitSet.valueOf(new long[]{x});
for (int i = bs.nextSetBit(0); i >=0 ; i = bs.nextSetBit(i+1)) {
System.out.println(1 << i);
}
Output:
1
2
8
32
If you really want them printed out as binary strings, here's a little hack on the above method:
long x = 0b101011;
char[] cs = new char[bs.length()];
Arrays.fill(cs, '0');
BitSet bs = BitSet.valueOf(new long[]{x});
for (int i = bs.nextSetBit(0); i >=0 ; i = bs.nextSetBit(i+1)) {
cs[bs.length()-i-1] = '1';
System.out.println(new String(cs)); // or whatever you want to do with this String
cs[bs.length()-i-1] = '0';
}
Output:
000001
000010
001000
100000
Scan through the bits one by one using an AND operation. This will tell you if a bit at one position is set or not. (https://en.wikipedia.org/wiki/Bitwise_operation#AND). Once you have determined that some ith-Bit is set, make up a string and print it. PSEUDOCODE:
public static void PrintAllSubbitstrings(int number)
{
for(int i=0; i < 32; i++) //32 bits maximum for an int
{
if( number & (1 << i) != 0) //the i'th bit is set.
{
//Make up a bitstring with (i-1) zeroes to the right, then one 1 on the left
String bitString = "1";
for(int j=0; j < (i-1); j++) bitString += "0";
System.out.println(bitString);
}
}
}
Here is a little test that works for me
public static void main(String[] args) {
int num = 0b1010;
int testNum = 0b1;
while(testNum < num) {
if((testNum & num) >0) {
System.out.println(testNum + " Passes");
}
testNum *= 2;
}
}
I am trying to figure out how to remove leading zeros from an array. The array is currently stored with the least significant bit at the first position.
Example: if number is 1101 it is stored in my array as: [1,1,0,1]. I do not want to flip the array or change it in anyway except remove the leading zeros. I have the bolded the leading zero that needs to be removed.
I am trying to just do this with just using the array and not converting it
Ex: current output : 0 1 1 0
Expected output: 0 1 1
public static byte[] normal(byte[] arr)
{
//check if all the numbers are 0 and last is 1
byte [] output = new byte[copy.length];
for(int i = arr.length;i<=0;i--)
{
if(arr[i]==1){
output[i]=copy[i];
}
}
return output;
}
Your problem is that the output array is the same size as the input array... the 0s that you skip are still going to be there because 0 is the default value of any item in an int[].
So, I would start at the end of your input array, and not actually initialize the output array until you hit the first 1. Then you know how big to make the output array.
public static byte[] normal(byte[] arr) {
byte[] output = null;
System.out.println(arr.length);
for (int i = arr.length-1; i >= 0; i--) {
if (arr[i] != 0) {
if (output == null) {
output = new byte[i+1];
}
output[i] = arr[i];
}
}
if (output == null) { // cover case where input is all 0s
output = new byte[0];
}
return output;
}
Your output array is too long. First you should count how many leading zeroes you have, and create an output array shorter than arr but that many elements:
public static byte[] normal(byte[] arr)
{
// Count the leading zeros:
int zeroes = 0;
while (arr[zeroes] == 0) {
++zeroes;
}
//check if all the numbers are 0 and last is 1
byte[] output = new byte[arr.length - zeroes];
for(int i = output.length - 1; i >= 0; ++i) {
output[i] = arr[i - zeroes];
}
return output;
}
Or better yet, use the built-in Arrays.copyOfRange:
public static byte[] normal(byte[] arr)
{
// Count the leading zeros:
int zeroes = 0;
while (arr[zeroes] == 0) {
++zeroes;
}
//check if all the numbers are 0 and last is 1
return Arrays.copyOfRange(zeroes, arr.length);
}
Iterate backwards over the array and find the index of the last occuring 1 (or you reach the front of the array). Then copy the array up to and including that index. Because you know the index of the final array, you know how large the returned array will have to be (size lastIndex + 1)
It's been a while since I've written java code, so this might not compile or run properly. But the code for this might look like this:
public static byte[] normal(byte[] arr)
{
//null check arr if desired
int indexOfLastNonZero = arr.length - 1;
boolean foundOne = false;
while(!foundOne && indexOfLastNonZero >= 0)
{
if (arr[indexOfLastNonZero] == (byte) 1)
foundOne = true;
else
indexOfLastNonZero -= 1;
}
if (foundOne)
{
byte[] output = new byte[indexOfLastNonZero + 1];
System.arraycopy( arr, 0, output, 0, output.length );
return output;
}
else
{
return null; //or size 0 array if you prefer
}
}
I suggest to count the number of continuous zeros from the last and then generate the output array which will be of the count size lesser than that the original size...
public static byte[] normal(byte[] arr)
{
int count = 0;
for(int i = arr.length-1;i>=0;i--)
{
if(arr[i]==1){
break;
}
count++;
}
byte [] output = new byte[copy.length-count];
for(int i = 0;i<(copy.length-count);i++) {
output[i] = copy[i];
}
return output;
}
I'm trying to get the position of the STX (0x02) from the byte array message below. If you see the message, it has 0x2 in a number of places but the only position I want is the STX one. I've been looping through it backwards using a for loop. I have to loop backwards btw. I've tried a number of ways but I'm having difficulty getting that position. One way I've tried but has not worked is, wherever a 0x2 is, and has elements of 3 or more between that and an ETX (0x3) in front of it get that position of that STX. But I'm doing something wrong because I keep on getting an error which I am having difficulty resolving. Can you please help?
EDIT: If there is a better way then my logic of finding that position (STX) by distinguishing it from the other 0x2, please can you provide that.
EDIT: I have to loop backwards as that is required by the instructions given to me.
EDIT: Here is the code:
//Test 3:
public String Test3(List<Byte> byteList) {
//checking positions of the STX and ETX
//looping through the array backwards
for (int i = byteList.size() - 1; i >= 0; i--) {
if (byteList.get(i) == STX && (i >= 3 && byteList.get(i) == ETX)) {
STXpos = i;
}
}
return STXpos;
}
byte[] validMsgWithRandomData = {0x32,0x32,0x32, //Random data
0x02, // STX
0x31,0x32,0x10,0x02,0x33, // Data 31 32 02 33
0x03, // ETX
0x31^0x32^0x02^0x33^0x03,// LRC calculated from the data (with the DLE removed) plus the ETX
0x2,0x3,0x00,0x02 //Random data
};
My first attempt with backward loop and in O(n) complexity.
EDIT : getting rid of candidate for STX.
EDIT 2 : This solution works at least for a few cases including OP's one (but it has not been tested extensively...).
final int NOTFOUND = -1;
final int ETX = 0x03;
final int STX = 0x02;
int stxpos = NOTFOUND;
int etxpos = NOTFOUND;
int etxcandidatepos = NOTFOUND;
for (int i = validMsgWithRandomData.length - 1; i >=0; --i)
{
if (ETX == validMsgWithRandomData[i])
{
etxcandidatepos = i;
if (NOTFOUND == etxpos)
{
etxpos = i;
stxpos = NOTFOUND;
}
}
else if (STX == validMsgWithRandomData[i])
{
if (NOTFOUND != etxpos)
{
stxpos = i;
if (NOTFOUND != etxcandidatepos)
{
etxpos = etxcandidatepos;
etxcandidatepos = NOTFOUND;
}
}
}
}
Since the amount of elements between STX and ETX is not a constant, i'd search in normal order and look for ETX after I find STX:
public String Test3(List<Byte> byteList) {
// find potential STX
for (int i = 0; i < byteList.size(); ++i) {
if (byteList.get(i) == STX) {
// make sure matching ETX exists
for (int j = i + 1; j < byteList.size(); ++j) {
if (byteList.get(j) == ETX) {
return i;
}
}
}
}
}
You can also do it in reverse order if you really want:
public String Test3(List<Byte> byteList) {
// find potential ETX
for (int i = byteList.size() - 1; i > 0; --i) {
if (byteList.get(i) == ETX) {
// make sure matching STX exists
for (int j = i - 1; j > 0; --j) {
if (byteList.get(j) == STX) {
return j;
}
}
}
}
}
By the way if you want to force a distance of elements between STX and ETX you can do it by changing j's initialization.
I'm working on a puzzle that involves analyzing all size k subsets and figuring out which one is optimal. I wrote a solution that works when the number of subsets is small, but it runs out of memory for larger problems. Now I'm trying to translate an iterative function written in python to java so that I can analyze each subset as it's created and get only the value that represents how optimized it is and not the entire set so that I won't run out of memory. Here is what I have so far and it doesn't seem to finish even for very small problems:
public static LinkedList<LinkedList<Integer>> getSets(int k, LinkedList<Integer> set)
{
int N = set.size();
int maxsets = nCr(N, k);
LinkedList<LinkedList<Integer>> toRet = new LinkedList<LinkedList<Integer>>();
int remains, thresh;
LinkedList<Integer> newset;
for (int i=0; i<maxsets; i++)
{
remains = k;
newset = new LinkedList<Integer>();
for (int val=1; val<=N; val++)
{
if (remains==0)
break;
thresh = nCr(N-val, remains-1);
if (i < thresh)
{
newset.add(set.get(val-1));
remains --;
}
else
{
i -= thresh;
}
}
toRet.add(newset);
}
return toRet;
}
Can anybody help me debug this function or suggest another algorithm for iteratively generating size k subsets?
EDIT: I finally got this function working, I had to create a new variable that was the same as i to do the i and thresh comparison because python handles for loop indexes differently.
First, if you intend to do random access on a list, you should pick a list implementation that supports that efficiently. From the javadoc on LinkedList:
All of the operations perform as could be expected for a doubly-linked
list. Operations that index into the list will traverse the list from
the beginning or the end, whichever is closer to the specified index.
An ArrayList is both more space efficient and much faster for random access. Actually, since you know the length beforehand, you can even use a plain array.
To algorithms: Let's start simple: How would you generate all subsets of size 1? Probably like this:
for (int i = 0; i < set.length; i++) {
int[] subset = {i};
process(subset);
}
Where process is a method that does something with the set, such as checking whether it is "better" than all subsets processed so far.
Now, how would you extend that to work for subsets of size 2? What is the relationship between subsets of size 2 and subsets of size 1? Well, any subset of size 2 can be turned into a subset of size 1 by removing its largest element. Put differently, each subset of size 2 can be generated by taking a subset of size 1 and adding a new element larger than all other elements in the set. In code:
processSubset(int[] set) {
int subset = new int[2];
for (int i = 0; i < set.length; i++) {
subset[0] = set[i];
processLargerSets(set, subset, i);
}
}
void processLargerSets(int[] set, int[] subset, int i) {
for (int j = i + 1; j < set.length; j++) {
subset[1] = set[j];
process(subset);
}
}
For subsets of arbitrary size k, observe that any subset of size k can be turned into a subset of size k-1 by chopping of the largest element. That is, all subsets of size k can be generated by generating all subsets of size k - 1, and for each of these, and each value larger than the largest in the subset, add that value to the set. In code:
static void processSubsets(int[] set, int k) {
int[] subset = new int[k];
processLargerSubsets(set, subset, 0, 0);
}
static void processLargerSubsets(int[] set, int[] subset, int subsetSize, int nextIndex) {
if (subsetSize == subset.length) {
process(subset);
} else {
for (int j = nextIndex; j < set.length; j++) {
subset[subsetSize] = set[j];
processLargerSubsets(set, subset, subsetSize + 1, j + 1);
}
}
}
Test code:
static void process(int[] subset) {
System.out.println(Arrays.toString(subset));
}
public static void main(String[] args) throws Exception {
int[] set = {1,2,3,4,5};
processSubsets(set, 3);
}
But before you invoke this on huge sets remember that the number of subsets can grow rather quickly.
You can use
org.apache.commons.math3.util.Combinations.
Example:
import java.util.Arrays;
import java.util.Iterator;
import org.apache.commons.math3.util.Combinations;
public class tmp {
public static void main(String[] args) {
for (Iterator<int[]> iter = new Combinations(5, 3).iterator(); iter.hasNext();) {
System.out.println(Arrays.toString(iter.next()));
}
}
}
Output:
[0, 1, 2]
[0, 1, 3]
[0, 2, 3]
[1, 2, 3]
[0, 1, 4]
[0, 2, 4]
[1, 2, 4]
[0, 3, 4]
[1, 3, 4]
[2, 3, 4]
Here is a combination iterator I wrote recetnly
package psychicpoker;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import static com.google.common.base.Preconditions.checkArgument;
public class CombinationIterator<T> implements Iterator<Collection<T>> {
private int[] indices;
private List<T> elements;
private boolean hasNext = true;
public CombinationIterator(List<T> elements, int k) throws IllegalArgumentException {
checkArgument(k<=elements.size(), "Impossible to select %d elements from hand of size %d", k, elements.size());
this.indices = new int[k];
for(int i=0; i<k; i++)
indices[i] = k-1-i;
this.elements = elements;
}
public boolean hasNext() {
return hasNext;
}
private int inc(int[] indices, int maxIndex, int depth) throws IllegalStateException {
if(depth == indices.length) {
throw new IllegalStateException("The End");
}
if(indices[depth] < maxIndex) {
indices[depth] = indices[depth]+1;
} else {
indices[depth] = inc(indices, maxIndex-1, depth+1)+1;
}
return indices[depth];
}
private boolean inc() {
try {
inc(indices, elements.size() - 1, 0);
return true;
} catch (IllegalStateException e) {
return false;
}
}
public Collection<T> next() {
Collection<T> result = new ArrayList<T>(indices.length);
for(int i=indices.length-1; i>=0; i--) {
result.add(elements.get(indices[i]));
}
hasNext = inc();
return result;
}
public void remove() {
throw new UnsupportedOperationException();
}
}
I've had the same problem today, of generating all k-sized subsets of a n-sized set.
I had a recursive algorithm, written in Haskell, but the problem required that I wrote a new version in Java.
In Java, I thought I'd probably have to use memoization to optimize recursion. Turns out, I found a way to do it iteratively. I was inspired by this image, from Wikipedia, on the article about Combinations.
Method to calculate all k-sized subsets:
public static int[][] combinations(int k, int[] set) {
// binomial(N, K)
int c = (int) binomial(set.length, k);
// where all sets are stored
int[][] res = new int[c][Math.max(0, k)];
// the k indexes (from set) where the red squares are
// see image above
int[] ind = k < 0 ? null : new int[k];
// initialize red squares
for (int i = 0; i < k; ++i) { ind[i] = i; }
// for every combination
for (int i = 0; i < c; ++i) {
// get its elements (red square indexes)
for (int j = 0; j < k; ++j) {
res[i][j] = set[ind[j]];
}
// update red squares, starting by the last
int x = ind.length - 1;
boolean loop;
do {
loop = false;
// move to next
ind[x] = ind[x] + 1;
// if crossing boundaries, move previous
if (ind[x] > set.length - (k - x)) {
--x;
loop = x >= 0;
} else {
// update every following square
for (int x1 = x + 1; x1 < ind.length; ++x1) {
ind[x1] = ind[x1 - 1] + 1;
}
}
} while (loop);
}
return res;
}
Method for the binomial:
(Adapted from Python example, from Wikipedia)
private static long binomial(int n, int k) {
if (k < 0 || k > n) return 0;
if (k > n - k) { // take advantage of symmetry
k = n - k;
}
long c = 1;
for (int i = 1; i < k+1; ++i) {
c = c * (n - (k - i));
c = c / i;
}
return c;
}
Of course, combinations will always have the problem of space, as they likely explode.
In the context of my own problem, the maximum possible is about 2,000,000 subsets. My machine calculated this in 1032 milliseconds.
Inspired by afsantos's answer :-)... I decided to write a C# .NET implementation to generate all subset combinations of a certain size from a full set. It doesn't need to calc the total number of possible subsets; it detects when it's reached the end. Here it is:
public static List<object[]> generateAllSubsetCombinations(object[] fullSet, ulong subsetSize) {
if (fullSet == null) {
throw new ArgumentException("Value cannot be null.", "fullSet");
}
else if (subsetSize < 1) {
throw new ArgumentException("Subset size must be 1 or greater.", "subsetSize");
}
else if ((ulong)fullSet.LongLength < subsetSize) {
throw new ArgumentException("Subset size cannot be greater than the total number of entries in the full set.", "subsetSize");
}
// All possible subsets will be stored here
List<object[]> allSubsets = new List<object[]>();
// Initialize current pick; will always be the leftmost consecutive x where x is subset size
ulong[] currentPick = new ulong[subsetSize];
for (ulong i = 0; i < subsetSize; i++) {
currentPick[i] = i;
}
while (true) {
// Add this subset's values to list of all subsets based on current pick
object[] subset = new object[subsetSize];
for (ulong i = 0; i < subsetSize; i++) {
subset[i] = fullSet[currentPick[i]];
}
allSubsets.Add(subset);
if (currentPick[0] + subsetSize >= (ulong)fullSet.LongLength) {
// Last pick must have been the final 3; end of subset generation
break;
}
// Update current pick for next subset
ulong shiftAfter = (ulong)currentPick.LongLength - 1;
bool loop;
do {
loop = false;
// Move current picker right
currentPick[shiftAfter]++;
// If we've gotten to the end of the full set, move left one picker
if (currentPick[shiftAfter] > (ulong)fullSet.LongLength - (subsetSize - shiftAfter)) {
if (shiftAfter > 0) {
shiftAfter--;
loop = true;
}
}
else {
// Update pickers to be consecutive
for (ulong i = shiftAfter+1; i < (ulong)currentPick.LongLength; i++) {
currentPick[i] = currentPick[i-1] + 1;
}
}
} while (loop);
}
return allSubsets;
}
This solution worked for me:
private static void findSubsets(int array[])
{
int numOfSubsets = 1 << array.length;
for(int i = 0; i < numOfSubsets; i++)
{
int pos = array.length - 1;
int bitmask = i;
System.out.print("{");
while(bitmask > 0)
{
if((bitmask & 1) == 1)
System.out.print(array[pos]+",");
bitmask >>= 1;
pos--;
}
System.out.print("}");
}
}
Swift implementation:
Below are two variants on the answer provided by afsantos.
The first implementation of the combinations function mirrors the functionality of the original Java implementation.
The second implementation is a general case for finding all combinations of k values from the set [0, setSize). If this is really all you need, this implementation will be a bit more efficient.
In addition, they include a few minor optimizations and a smidgin logic simplification.
/// Calculate the binomial for a set with a subset size
func binomial(setSize: Int, subsetSize: Int) -> Int
{
if (subsetSize <= 0 || subsetSize > setSize) { return 0 }
// Take advantage of symmetry
var subsetSizeDelta = subsetSize
if (subsetSizeDelta > setSize - subsetSizeDelta)
{
subsetSizeDelta = setSize - subsetSizeDelta
}
// Early-out
if subsetSizeDelta == 0 { return 1 }
var c = 1
for i in 1...subsetSizeDelta
{
c = c * (setSize - (subsetSizeDelta - i))
c = c / i
}
return c
}
/// Calculates all possible combinations of subsets of `subsetSize` values within `set`
func combinations(subsetSize: Int, set: [Int]) -> [[Int]]?
{
// Validate inputs
if subsetSize <= 0 || subsetSize > set.count { return nil }
// Use a binomial to calculate total possible combinations
let comboCount = binomial(setSize: set.count, subsetSize: subsetSize)
if comboCount == 0 { return nil }
// Our set of combinations
var combos = [[Int]]()
combos.reserveCapacity(comboCount)
// Initialize the combination to the first group of set indices
var subsetIndices = [Int](0..<subsetSize)
// For every combination
for _ in 0..<comboCount
{
// Add the new combination
var comboArr = [Int]()
comboArr.reserveCapacity(subsetSize)
for j in subsetIndices { comboArr.append(set[j]) }
combos.append(comboArr)
// Update combination, starting with the last
var x = subsetSize - 1
while true
{
// Move to next
subsetIndices[x] = subsetIndices[x] + 1
// If crossing boundaries, move previous
if (subsetIndices[x] > set.count - (subsetSize - x))
{
x -= 1
if x >= 0 { continue }
}
else
{
for x1 in x+1..<subsetSize
{
subsetIndices[x1] = subsetIndices[x1 - 1] + 1
}
}
break
}
}
return combos
}
/// Calculates all possible combinations of subsets of `subsetSize` values within a set
/// of zero-based values for the set [0, `setSize`)
func combinations(subsetSize: Int, setSize: Int) -> [[Int]]?
{
// Validate inputs
if subsetSize <= 0 || subsetSize > setSize { return nil }
// Use a binomial to calculate total possible combinations
let comboCount = binomial(setSize: setSize, subsetSize: subsetSize)
if comboCount == 0 { return nil }
// Our set of combinations
var combos = [[Int]]()
combos.reserveCapacity(comboCount)
// Initialize the combination to the first group of elements
var subsetValues = [Int](0..<subsetSize)
// For every combination
for _ in 0..<comboCount
{
// Add the new combination
combos.append([Int](subsetValues))
// Update combination, starting with the last
var x = subsetSize - 1
while true
{
// Move to next
subsetValues[x] = subsetValues[x] + 1
// If crossing boundaries, move previous
if (subsetValues[x] > setSize - (subsetSize - x))
{
x -= 1
if x >= 0 { continue }
}
else
{
for x1 in x+1..<subsetSize
{
subsetValues[x1] = subsetValues[x1 - 1] + 1
}
}
break
}
}
return combos
}