Getting unexpected position value from binarySearch method in java - java

Currently working with java basics.While learning I've written the following code.
import java.util.*;
class RemoveDuplicates{
public static void main(String[] args) {
int[] arr = {1,2,3,1,5,2,3};
int[] out = {1,2,3,1,5,2,3};
for(int each : arr){
System.out.println("Element "+each+" at "+Arrays.binarySearch(out,each));
}
}
}
My expected output:
Element 1 at 3
Element 2 at 5
Element 3 at 6
Element 1 at 3
Element 5 at 4
Element 2 at 5
Element 3 at 6
My actual output:
Element 1 at 3
Element 2 at 5
Element 3 at 6
Element 1 at 3
Element 5 at -8
Element 2 at 5
Element 3 at 6
In my actual output at element 5 why I'm getting -8 from Arrays.binarySeach(out,each) function?
Explain me this please.

Always remember for binary search to work you must sort the array.
Use can use Arrays.sort() for sorting
import java.util.*;
class RemoveDuplicates{
public static void main(String[] args) {
int[] arr = {1, 2, 3, 1, 5, 2, 3};
int[] out = {1, 2, 3, 1, 5, 2, 3};
Arrays.sort(out);
for(int each : arr) {
System.out.println("Element "+each+" at "+Arrays.binarySearch(out,each));
}
}
}

If u want to use binary search, u should sort the array first.
add
Arrays.sort(out);
Besides, FYI, there is no guarantee for multiple elements.
here's some infs for Arrays.binarySearch(int[], int)
Searches the specified array of ints for the specified value using the binary search algorithm. The array must be sorted (as by the sort(int[]) method) prior to making this call. If it is not sorted, the results are undefined. If the array contains multiple elements with the specified value, there is no guarantee which one will be found.

Related

Is there something wrong with the code I made?

So our project is all about sets and it should display the union, intersection, difference and I am having doubts on my code because in the example given to us by our teacher, the elements of the set was already given and in the output there is no "null" result in the union and intersection BUT our challenge is to have the elements to be user input AND in my code there is a "null" result in my union and intersection. Is that okay?
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
Set<Integer> a = new HashSet<Integer>();
a.addAll(Arrays.asList(new Integer[5]));
for () {
//scan code...
}
Set<Integer> b = new HashSet<Integer>();
b.addAll(Arrays.asList(new Integer[5]));
for () {
//scan code...
}
// UNION
Set<Integer> union = new HashSet<Integer>(a);
union.addAll(b);
System.out.print("\nUnion of the two Set: ");
System.out.println(union);
// INTERSECTION
Set<Integer> intersection = new HashSet<Integer>(a);
intersection.retainAll(b);
System.out.print("Intersection of the two Set: ");
System.out.println(intersection);
// DIFFERENCE
Set<Integer> difference = new HashSet<Integer>(a);
difference.removeAll(b);
System.out.print("Difference of the two Set: ");
System.out.println(difference);
}
OUTPUT: (TEACHER'S GIVEN CODE!)
Union of the two Set[0, 1, 2, 3, 4, 5, 7, 8, 9]
Intersection of the two Set[0, 1, 3, 4]
Difference of the two Set[2, 8, 9]
MY OUTPUT:
Set A :
3 4 2 1 0
Set B :
7 4 1 9 8
Union of the two Set: [null, 0, 1, 2, 3, 4, 7, 8, 9]
Intersection of the two Set: [null, 1, 4]
Difference of the two Set: [0, 2, 3]
You have the null because of these two lines in your code :
a.addAll(Arrays.asList(new Integer[5]));
b.addAll(Arrays.asList(new Integer[5]));
Just remove these two lines and your code should work.
I agree with #theincrediblethor, but as an explanation...
You are initializing a Set as if it were an array. Initially a Set is empty, and an array is uninitialized. You don't want to put "empty" Integers [null, null, null, null, null] in the Set, they will just stay there even when you add the real Integers on input.
Since Sets don't allow duplicates, 4 of the empty Integers are dropped upon add.
So you are left with 1 null and all of your input.
In your line
a.addAll(Arrays.asList(new Integer[5]));
new Integer[5] is creating an array of 5 null values [ null,null,null,null,null ]
Arrays.asList() just turns it into a Collection(List) of 5 null values
a.addAll() adds all the elements of your Collection into your Set and, as the values are unique, you only add one null
So you just have to remove that line, same for Set b
Try this code and you will see the step by step
import java.util.Set;
import java.util.HashSet;
import java.util.Arrays;
public class Main
{
public static void main(String[] args) {
Integer[] arr = new Integer[5];
System.out.println(Arrays.toString(arr));
Set<Integer> a = new HashSet<Integer>();
a.addAll(Arrays.asList(arr));
System.out.println(a);
a.add(1);
System.out.println(a);
}
}
it prints

Why is my algorithm to find the total amount of unique integers in a subarray (contiguous), not working for larger amounts of Integers and subarrays?

My algorithm to find the maximum number of unique integers among all possible contiguous subarrays doesn't work for larger amounts of Integers and subarrays.
For instance, I have to read a total amount of 6 Integers from the console and each subarray has a size of 3.
So, for this kind of input 5 3 5 2 3 2
my program should print 3 and this works fine.
The first subarray stores 5 3 5 so the number of unique Integers is 2.
The second subarray stores 3 5 2 so the number of unique Integers is 3.
The third subarray would also print 3 because it stores 5 2 3 and so on...
But, it seems like my algorithm can't handle a total amount of 100000 Integers with a subarray size of 99877.
Can anyone explain me, what I have done wrong?
FYI: I have to use a Deque implementation like LinkedList or ArrayDeque
for (int i = 0; i < totalAmountOfIntegers; i++) {
int anyIntegerNumber = consoleInput.nextInt();
arrayDequeToStoreAllIntegers.addLast(anyIntegerNumber);
hashSetToStoreUniqueIntegers.add(anyIntegerNumber);
if (arrayDequeToStoreAllIntegers.size() == sizeOfEachArrayDequeAsSubArray) {
if (hashSetToStoreUniqueIntegers.size() > quantityOfUniqueIntegersInSubarray) {
quantityOfUniqueIntegersInSubarray = hashSetToStoreUniqueIntegers.size();
}
int firstNumberInDeque = arrayDequeToStoreAllIntegers.remove();
if (hashSetToStoreUniqueIntegers.size() == sizeOfEachArrayDequeAsSubArray) {
hashSetToStoreUniqueIntegers.remove(firstNumberInDeque);
}
}
}
The answer would be simply the unique integers in the whole array, since the array is the superset of all subarrays, all numbers would be present in it
Just find how many unique element exist
To be honest, i don't understand your algorithm. I don't really get what the variables are referring to (although they seem to be named in a semantic way).
But what about this:
import java.util.HashSet;
import java.util.Set;
public class UniqueIntegers {
public static void main(String[] args) {
UniqueIntegers ui = new UniqueIntegers();
Integer[][] integers = {
{3,5,3,4,6},
{1,6,3,2,4},
{2,3,4},
{3,3,6,9,2}
};
Set<Integer> unique = ui.uniqueIntegers(integers);
System.out.println("Unique Integers: " + unique.size());
System.out.println("Integers: " + unique);
}
private Set<Integer> uniqueIntegers(Integer[][] ints){
Set<Integer> result = new HashSet<Integer>();
for (Integer[] iSub : ints){
for (Integer i : iSub){
result.add(i);
}
}
return result;
}
}
It prints:
Unique Integers: 7
Integers: [1, 2, 3, 4, 5, 6, 9]
After a day of researching, I have found my mistake.
My third IF-Statement is wrong. I am comparing, if the size of my HashSet variable is equal to the maximum size of elements each subarray can hold.
Instead, I should compare, if my int variable firstNumberInDeque, which I remove first from my ArrayDeque variable, contains another int variable with the same value. So if this is true, my HashSet variable remains unchanged.
But, if my ArrayDeque variable doesn't contain another int with the same value of firstNumberInDeque than firstNumberInDeque should be removed from my HashSet variable.
Here is the right code:
int firstNumberInDeque = arrayDequeToStoreAllIntegers.remove();
if (!arrayDequeToStoreAllIntegers.contains(firstNumberInDeque)) {
hashSetToStoreUniqueIntegers.remove(firstNumberInDeque);
}

please help me out its very confusing java code

public class Test {
public static void main(String[] args) {
int arr[] = {1,2,3,4};
int i=0;
while (i<20)
{
System.out.println(arr[?]);
}
}}
what should we write in place of ? so that ArrayIndexOutOfBounds exception do not occur and the output is as follows?
1
2
3
4
1
2
3
4
1
2
3
4
1
2
3
4
1
2
3
4
Use modulu 4, since that would give you integers between 0 and 3, which are the indices of your array :
System.out.println(arr[i%4]);
But don't forget to increment i.
int arr[] = {1,2,3,4};
int i=0;
while (i<20)
{
System.out.println(arr[i%4]);
i++;
}
A more succinct solution (though less readable in my opinion), would be to combine the two statements :
System.out.println(arr[(i++)%4]);
You want the array index to always be one of {0, 1, 2, 3}.
The mod n (%n) operation will get you result among [0, n-1].
So you can write it like:
System.out.println(arr[(i++)%4]);
With this solution one can vary the length of the array. And 'i' can take any value. So that Array Index Out Of Bound exception do not occur.
System.out.print(arr[i++%arr.length]);

Can someone correct the way I understand this code because the output is different than what I think?

public class Test{
public static void main(String[] args){
int[] a = {3, 2, 5, 21}; // created an array with 4 elements
int b,c;
for (b=0; b<=2; b++)//for loop that will have 3 iterations
{
if (a[b] < a[b+1])
{
c=a[b];//this
a[b] = a[b+1];//is
a[b+1] = c;//swapping
}
}
for(b=0; b<4; b++)
{
System.out.println(a[b]);
}
}
}
This outputs :
3 5 21 2
What I got when I was writing it down:
3 5 21 21
Could someone tell me how to approach it in my thoughts?
Well if you really want to just trace out the program you could go through each iteration of that first for-loop by hand (the second loop just prints the contents of a).
Before the loop starts, a holds
{3, 2, 5, 21}
First iteration (b = 0):
a[0] is not less than a[1] so we do nothing.
Second iteration (b = 1):
a[1] is less than a[2], so we swap them. Now a holds
{3, 5, 2, 21}
Third iteration (b = 2):
a[2] is less than a[3], so we swap them. Now a holds
{3, 5, 21, 2}
which is what gets printed subsequently.
Well, the code always outputs the initial elements of a, possibly permuted. Thus your expectation can't possibly have been correct, since it lost 2 and made 21 appear twice.
Well you got lost at the 3rd iteration so I'll start there.
The array is {3, 5, 2, 21}.
b = 2
if (a[b] < a[b+1]) is equivalent to if (2 < 21), this is true, so...
c=a[b];//this -> c = 2
a[b] = a[b+1];//is -> a[2] = 21
a[b+1] = c;//swapping -> a[2+1] = 2
so now a[2] = 21 and a[3] = 2 and the final array is:
{3, 5, 21, 2}
Each time you run the full outer loop you will end up with the next smallest element at the end of the array. So as you're only running the loop once you end up with 2 (being the first smallest element) at the end of the array.
As others have mentioned, if you want to make this a complete sort then you need more iterations of the main loop to complete the sort (n-1, where n is the length of the array, so in this case you would need to run the loop 3 times).

Trouble understanding Multidimensional Arrays

So i am trying to understand multidimensional arrays a little better. So far, I understand there are 2 way to construct these arrays. One is
int[][] b = { { 1, 2 }, { 3, 4, 5 } };
The first array constructs row 0 with 2 columns ( column 0 and column 1). What i don't understand is why are these numbers chosen. Does it always have to be in numerical order, or do the numbers mean something more? If i were to create a new row would it start with 6? Would it just be better for me to construct it this way?
int[][] b = new int [2][];
b[0] = new int [2];
b[1] = new int [3];
Thanks for your help.
Those numbers are meant to be examples. You need not start your next row with "6" if it's not what your solution demands.
Either manner of construction is acceptable. You'd use the second one if you had to compute the values and didn't know them beforehand.
1, 2, 3, 4, and 5 are just data that got entered in this new array.
The array would look like this:
[
[1, 2]
[3, 4, 5]
]
so [0][0] = 1; [1][0] = 3, [1][2] = 5 etc
Those values are just chosen as example.
First: there is no multi-dimensional arrays in Java. There are only arrays containing arrays. Arrays of arrays if you prefer.
int[][] b = { { 1, 2 }, { 3, 4, 5 } };
constructs an array containing 2 arrays of int. The first array contains the numbers 1 and 2, and the second contains the numbers 3, 4 and 5. These numbers could be anything you want. The line declares and populates the array at the same time.
int[][] b = new int [2][];
b[0] = new int [2];
b[1] = new int [3];
constructs an array of arrays of ints, containing two null elements. Then, the first element of the outer array is initialized with an array of 2 ints, and the second element of the outer array is initialized with an array of 3 ints. All the ints are initialized to their default value: 0.

Categories