I am using BitSet to represent possible hours where lectures are filled in, the case is that when you put to false the corner bits, they are simplified, this means that they are not anymore in the BitSet. How can I ask BitSet to not simplify?
To make my explanation clearer this is the code:
for(Map.Entry<GrupAssig, BitSet> entry : bitsetPerGrup.entrySet()){
BitSet bitset = entry.getValue();
//n franges per dia
int numFranges = UnitatDocent.getNumFranges();
int indexDia = this.dia.id() * numFranges;
bitset.clear(indexDia, indexDia+numFranges);
}
Imagine that the bitset has 60 bits by default, and numFranges=12 and this.dia.id()=4. This would make the last twelve bits set to 0. The result I get is:
111111111111111111111111111111111111111111111111
But if this.dia.id()=3 I get:
11111111111111111111111111111111111100000000000011111111111
And you can print the BitSet this way:
public static void printBitset(BitSet b) {
StringBuilder s = new StringBuilder();
for( int i = 0; i < b.length(); i++ )
{
s.append( b.get( i ) == true ? 1 : 0 );
}
System.out.println( s );
}
Which demonstrates what I am saying.
Thank you.
Here's the documentation for BitSet.length:
length()
Returns the "logical size" of this BitSet: the index of the highest set bit in the BitSet plus one.
If you need to print out a certain number of bits (e.g. 60) then use a constant instead of ".length()" for your loop. You can call ".get(index)" on any index regardless of the length and it will give you the result for that bit.
For instance the following code produces "0000011000":
import java.util.BitSet;
public class Main {
public static void main(String[] args) {
BitSet bits = new BitSet();
bits.set(5);
bits.set(6);
StringBuilder bitString = new StringBuilder();
for (int i = 0; i < 10; i++) {
bitString.append(bits.get(i) ? "1" : "0");
}
System.out.println(bitString.toString());
}
}
Related
Trying to figure the error with this code. This works for small samples but fails for huge numbers (I don't have a large sample in my hand though).
The solution worked for the following tests.
private static final int[] A = {9,3,9,3,9,7,9};
private static final int[] A2 = {9,3,9};
private static final int[] A3 = {9,3,9,3,9,7,7,2,2,11,9};
#Test
public void test(){
OddOccurance oddOccurance =new OddOccurance();
int odd=oddOccurance.solution(A);
assertEquals(7,odd);
}
#Test
public void test2(){
OddOccurance oddOccurance =new OddOccurance();
int odd=oddOccurance.solution(A2);
assertEquals(3,odd);
}
#Test
public void test3(){
OddOccurance oddOccurance =new OddOccurance();
int odd=oddOccurance.solution(A3);
assertEquals(11,odd);
}
when an array is given with an odd number of integers (except one integer other integers can be repeated). The solution is to find the non-repeating integer. Any other better ideas (Time and space optimized) to implement this as well, welcome.
public int solution(int[] A) {
// write your code in Java SE 8
Map<Integer, List<Integer>> map = new HashMap<>();
int value = 0;
//iterate throught the list and for each array value( key in the map)
// set how often it appears as the value of the map
for (int key : A) {
if (map.containsKey(key)) {
map.get(key).add(value);
} else {
List<Integer> valueList = new ArrayList<>();
valueList.add(value);
map.put(key, valueList);
}
}
Set<Map.Entry<Integer, List<Integer>>> entrySet = map.entrySet();
// en
for (Map.Entry<Integer, List<Integer>> entry : entrySet) {
if (entry.getValue().size() == 1) {
return entry.getKey();
}
}
return 0;
}
Update
Looking at failed outputs
WRONG ANSWER, got 0 expected 42
WRONG ANSWER, got 0 expected 700
It seems it didn't even go to the for loop but just return 0
It's a standard problem, if the actual statement is the following:
each number except one appears even number of times; the remaining number appears once.
The solution is to take xor of all numbers. Since every repeating number occures even number of times, it will cancel itself. The reason is that xor is commutative:
a xor b xor c = a xor c xor b = c xor b xor a = etc.
For example, in case of 1, 2, 3, 1, 2
1 xor 2 xor 3 xor 1 xor 2 =
(1 xor 1) xor (2 xor 2) xor 3 =
0 xor 0 xor 3 =
3
One approach would be to create a new array containing the frequency of each value. You could start by looping through your initial array to calculate the maximum value in it.
For example, the array {9,3,9,3,9,7,7,2,2,11,9} would have a maximum value of 11. With this information, create a new array that can store the frequency of every possible value in your initial array. Then, assuming there is only one integer that repeats once, return the index of the new array that has a frequency of 1. This method should run in O(n) where n is the size of the input array.
Here's an implementation:
public int solution(int[] inp)
{
int max = inp[0];
for(int i = 1; i < inp.length; i++)
{
if(inp[i] > max)
max = inp[i];
}
int[] histogram = new int[max + 1]; //We add 1 so we have an index for our max value
for(int i = 0; i < inp.length; i++)
histogram[inp[i]]++; //Update the frequency
for(int i = 0; i < histogram.length; i++)
{
if(histogram[i] == 1)
return i;
}
return -1; //Hopefully this doesn't happen
}
Hope this helps
It's hard to know why yours failed without the actual error message. Regardless, as your array input gets very large, your internal data structure grows accordingly, but doesn't need to. Instead an array of Integer as the value, we can just use one Integer:
public int solution(int[] a) {
Integer ONE = 1;
Map<Integer, Integer> map = new HashMap<>();
for (int key : a) {
Integer value = (map.containsKey(key)) ? map.get(key) + ONE : ONE;
map.put(key, value);
}
for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
if (entry.getValue().equals(ONE)) {
return entry.getKey();
}
}
return -1;
}
I'm assuming the odd array length requirement is to avoid an array of length of two, where the items would both be unduplicated or duplicated.
Since we don't need the actual total, we can simplify this further and just consider parity. Here's a rework that does and uses the evolving new rules of this question, looking for the odd man out:
public int solution(int[] a) {
Map<Integer, Boolean> odd = new HashMap<>();
for (int key : a) {
odd.put(key, (odd.containsKey(key)) ? ! odd.get(key) : Boolean.TRUE);
}
for (Map.Entry<Integer, Boolean> entry : odd.entrySet()) {
if (entry.getValue()) {
return entry.getKey();
}
}
return 0;
}
Returns zero on failure as we now know:
A is an integer within the range [1..1,000,000,000]
Suppose I have a number 123. I need to see if I get all digits 1 through 9, including 0. The number 123 has three digits: 1,2, and 3. Then I multiply it by 2 and get 246 (I get digits 2, 4, 6). Then I multiply it by 3 and I get 369. I keep doing incremental multiplication until I get all digits.
My approach is the following:
public int digitProcessSystem(int N) {
String number = Integer.toString(N);
String [] arr = number.split("");
// List <Integer> arr2 = new ArrayList<>();
for (Integer i = 0; i < arr.length; i++) {
try {
arr2[i] = Integer.parseInt(arr[i]);
} catch (NumberFormatException e) {
}
}
count =0;
boolean contains = IntStream.of(arr2).anyMatch(x -> x == 1|| x==2 ||x == 3|| x==4|| x == 5|| x==6 ||x == 7|| x==8||x == 9|| x==0);
}
I really don't know how can I keep doing the boolean for digits that did not match in the first trail above because I will definitely get any one of the all digits in the above boolean search. How can I get that if some specific digits are present and some are not so that I can multiply the actual number to do the search for the digits that were not found in the first trial; just like the way I defined in the beginning.
You could wrap that into a while loop and include the numbers into a Set. Once the set has the size 10 all digits are present in the number. I´d also suggest to use a long instead of an int or you´ll be getting wrong results or run into an excpetion. Here´s some example code for this:
private static long digitProcessSystem(long N) {
long numberN = N;
String number = Long.toString(N);
// calculate 10 digits number here yet
if (number.length() < 10) {
// using the smallest possible number with each digit
// By using this number we are most likely allmost at the result
// This will increase the performance for small digits heavily.
long divider = 1023456789L / numberN;
numberN *= divider;
}
number = Long.toString(numberN);
String[] arr = number.split("");
Set<String> input = new HashSet<>(Arrays.asList(arr));
while(input.size() != 10){
// add N to number
numberN += N;
// Parse the new number
number = Long.toString(numberN);
// split
arr = number.split("");
// clear set
input.clear();
// Add the new numbers to the set. If it has the size 10 now the loop will stop and return the number.
input.addAll(Arrays.asList(arr));
};
return numberN;
}
public static void main(String[] args) {
System.out.println(digitProcessSystem(123));
}
output:
1023458769
I'm not sure what is your end goal. But you can use a HashSet and do something like this in order to achieve what you are trying to achieve:
public static void main (String[] args) throws Exception {
long number = 123L, counter = 1000000000L / number;
while(digitProcessSystem(number * counter++));
System.out.println("Number: " + number * (counter - 1));
}
public static boolean digitProcessSystem(long input) {
char[] arr = Long.toString(input).toCharArray();
Set<Character> set = new HashSet<>();
for (int i = 0; i < arr.length; i++) {
set.add(arr[i]);
}
return set.size() != 10;
}
Output:
Number: 1023458769
without using java language Facilities and hashset:
private static long digitProcessSystem(long N) {
long numberN = N;
String number = Long.toString(N);
String[] arr = number.split("");;
int arr2=new int[10];
int sum=0;
while(sum != 10){
sum=0;
// add N to number
numberN += N;
// Parse the new number
number = Long.toString(numberN);
// If it doesn´t have 10 digitis continue here yet
if(number.length() < 10) continue;
// split
arr = number.split("");
for(int i=0;i<arr.length;i++){
arr2[arr]=1;
}
for(int i=0;i<10;i++){
sum+=arr2[i];
}
};
return numberN;
}
Generally, if you want to process the characters of a String, don’t do it by splitting the string into substrings. Note that every CharSequence, including String, has the methods chars() and codepoints() allowing to process all characters as IntStream.
To check whether all digits from '0' to '9' are present, we can use chars() (don’t have to think about surrogate pairs) and do it straight-forward, map them to their actual number by subtracting '0', filter out all non-digits (just to be sure), then, map them to an int where the nth bit is set, so we can binary or them all together and check whether all of the lowest ten bits are set:
public static boolean hasAllDigits(String s) {
return s.length()>9 &&
s.chars().map(c -> c-'0').filter(c -> c>=0 && c<=9)
.map(c -> 1 << c).reduce(0, (a,b)->a|b) == 0b1111111111;
}
As a bonus, a length-check is prepended as a String must have at least ten characters to contain all ten digits, so we can short-cut if it hasn’t.
Now, I’m not sure about your actual task. If you just want to iterate until encountering a number having all digits, it’s quite simple:
long number=123;
for(long l = 1, end = Long.MAX_VALUE/number; l < end; l++) {
long candidate = number * l;
if(hasAllDigits(String.valueOf(candidate))) {
System.out.println("found: "+candidate);
return;
}
}
System.out.println("not found within the long range");
But if you want to know when you encountered all digits within the sequence of numbers, we have to adapt the test method and keep the bitset between the iterations:
public static int getDigits(String s) {
return s.chars().map(c -> c-'0').filter(c -> c>=0 && c<=9)
.map(c -> 1 << c).reduce(0, (a,b)->a|b);
}
long number=123;
int digits=0;
for(long l = 1, end = Long.MAX_VALUE/number; l < end; l++) {
long candidate=number * l;
int newDigits=digits | getDigits(String.valueOf(candidate));
if(newDigits != digits) {
System.out.printf("pos %10d: %10d%n", l, candidate);
digits=newDigits;
if(digits == 0b1111111111) {
System.out.println("encountered all digits");
break;
}
}
}
if(digits != 0b1111111111) {
System.out.println("did not encounter all digits within the long range");
}
This method will only print numbers of the sequence which have at least one digit not encountered before, so you can easily see which one contributed to the complete set and will see at most ten numbers of the sequence.
I need help sorting an integer array using selection sort. It won't sort for some reaons. Below is my demo/main.
02
20
01
it should be
01
02
20
My demo/main:
public static void main(String[] args) {
SelectionSortArray[] ints = new SelectionSortArray[3];
ints [0] = new SelectionSortArray(02);
ints [1] = new SelectionSortArray(20);
ints [2] = new SelectionSortArray(01);
System.out.println("Unsorted array: ");
for (int index = 0; index < ints.length; index++) {
System.out.println(ints[index]);
}
SelectionSort.selectionSort(ints);
System.out.println(" ");
System.out.println("Sorted array using selection sort: ");
for (int index = 0; index < ints.length; index++) {
System.out.println(ints[index]);
}
}
Your compareTo method in the SelectionSortArray class is incorrect. The compareTo method must return an int less than zero if the current object is less than the other object, yet you have it returning 1.
Quoting from the linked Javadocs:
Compares this object with the specified object for order. Returns a
negative integer, zero, or a positive integer as this object is less
than, equal to, or greater than the specified object.
Try these changes:
if (num == other.num) {
result = 0; // This was correct; no change here.
} else if (num < other.num) {
result = -1; // Changed from 1 to -1.
} else {
result = 1; // 1 or 2 is fine, as long as it's positive
}
Your CompareTo function is wrong. Just change it to:
public int compareTo(SelectionSortArray other) {
return num.compareTo(other.num);
}
The key is the -1 / 0 / 1 return codes, rather than the "0,1,2" that you're using.
Generally if you're comparing built in types, it's easier to just delegate to the built in comparison operators.
Note: To use "num.compareTo" you need to use "Integer" rather than "int". If you want to stick with "int", you need the solution posted by rgettman.
Note that along with the changes to compareTo,
return Integer.compare(this.num,other.num)
Which is implemented to return what you are returning but in a concise way
public static int compare(int x, int y) {
return (x < y) ? -1 : ((x == y) ? 0 : 1);
}
if you want to see the printed output in the way you listed in your question use
System.out.format("%02d%n",ints[index].num);
or alter toString() to return String.format("%02d",num)
You might also want to see java.util.Arrays source code so see how few other similar methods have been implemented. Also consider changing your class name to indicate that it holds number CustomNumber and encapsulate your class to avoid direct access to num.
And another Interesting catch in your code
SelectionSortArray[] ints = new SelectionSortArray[8];
ints[0] = new SelectionSortArray(01);
ints[1] = new SelectionSortArray(02);
ints[3] = new SelectionSortArray(03);
ints[4] = new SelectionSortArray(04);
ints[5] = new SelectionSortArray(05);
ints[6] = new SelectionSortArray(06);
ints[7] = new SelectionSortArray(07);
ints[8] = new SelectionSortArray(08);//???
if you precede a number with 0 it will be an Octal number and allowed digits are 0 - 7 hence you will see compilation error above. Also
System.out.println(0123);
System.out.println(0234);
will not print
0123
0234
as you (un)expected !
83
156
Just be cautious while using octal numbers in your code.
I have:
public byte[] bytes = new byte[5]; //BitComp Class
public BitSet bits = new BitSet(40);
and the getters and setters in class named BitComp. The following class sets all the first 8 bits to 1(byte[0]).After that it converts all bytes to BitSet. Now after that when it sets the 2nd bit to true and prints both of them.
import java.util.BitSet;
public class TestBitSet {
public void testBit(){
BitComp comp = new BitComp();
comp.bytes[0] |= 0xFF;
comp.setBits(getBitsFromByte(comp.getBytes()));
System.out.println(toCharArray(comp.getBits()));
BitSet bs = comp.getBits();
bs.set(1,true);
comp.setBits(bs);
System.out.println(toCharArray(comp.getBits()));
}
private BitSet getBitsFromByte(byte[] barray)
{
BitSet bits=new BitSet();
if(barray!=null)
{
for (int i=0; i<barray.length*8; i++)
{
if ((barray[barray.length-i/8-1]&(1<<(i%8)))!= 0)
{
bits.set(i);
}
}
}
return bits;
}
public static char[] toCharArray(final BitSet bs)
{
final int length = bs.length();
final char[] arr = new char[length];
for(int i = 0; i < length; i++)
{
arr[i] = bs.get(i) ? '1' : '0';
}
return arr;
}
public static void main(String args[]){
TestBitSet tbs = new TestBitSet();
tbs.testBit();
}
}
Output:0000000000000000000000000000000011111111 <- 0th
0th-> 0100000000000000000000000000000011111111
There should not ne any change cause byte[0] contains the first 8 elements and I am setting the 2nd element as 1 with BitSet operation.
So BitSet is approaching from LHS and Byte array is stored from RHS. How to approach this problem? Is there a problem in getBitsFromByte method?
Please Suggest.
Thanks
You don't provide the code for BitComp, however it appears to me that you determine how to translate bits into bytes and what order to print the bytes.
Its entirely up to you what order you what things to be set or printed out.
Just add a little math into your Set: ((byteNumber*8)+(7-bitNumber))
So this probably would be easy if done like this
public static [] nums(int j)
{
int num = 12345;
int[]thenums = [5];
for(int i=0; i<5; i++)
{
thenums[4-i] = num%10;
num = num/10;
}
return the nums
}
i get {1,2,3,4,5}
but for some reason if the number starts with a 0 then it does not work
how to make this work if the number were
int num = 02141;
thanks
EDIT: Doh... I'd completely forgotten about octal literals. That explains why the value is showing up differently. (02141 is treated as an octal literal; it's not the same value as 2141.)
However, it sounds like the OP wants to "remember" the number of leading zeroes in a number. There's no way of doing that as an integer, because it's just remembering a value. What's the difference between seeing "3" birds and seeing "0000003" birds?
If you have a number representation where the leading zeroes are important, you're not just talking about an integer quantity, which is all that an int represents.
Where are you getting your input from? It sounds like you should just be maintaining it as a string from the start.
If you always want 5 digits, that's easy to do - and your current code should do it (when amended to actually compile) - something like this:
public class Test
{
public static void main(String[] args)
{
int[] digits = getDigits(123);
for (int digit : digits)
{
System.out.print(digit); // Prints 00123
}
}
public static int[] getDigits(int value)
{
int[] ret = new int[5];
for (int i = 4; i >=0 ; i--)
{
ret[i] = value % 10;
value = value / 10;
}
return ret;
}
}
Now that's hard-coded to return 5 digits. If you don't know the number of digits at compile-time, but you will know it at execution time, you could pass it into the method:
public static int[] getDigits(int value, int size)
{
int[] ret = new int[size];
for (int i = size - 1; i >=0 ; i--)
{
ret[i] = value % 10;
value = value / 10;
}
// Perhaps throw an exception here if value is not 0? That would indicate
// we haven't captured the complete number
return ret;
}
What happens in your code is that 02141 is not the same as 2141; the first is octal (equivalent to 1121 decimal), while the second is 2141 decimal.
The relevant part of the Java Language Specification is JLS 3.10.1, specifically the grammar productions for DecimalNumeral and OctalNumeral.