Getting extra digit while trying to union two arrays in JAVA - java

In a task I have I need to union two sets(arrays of integers), but from some reason i'm getting the wrong output...
this is the attributes of the class set:
private int []set;
private int counter;
private int max = 10;
this is the constructor I use to get numbers(i needed to use varags because i need to be able to change the number of elements in the set):
public Set (int...numbers) {
set = new int[max];
counter = 0;
for (int i = 0; i < numbers.length; i++) {
if (!this.isMember(numbers[i])) {
this.set[this.counter] = numbers[i];
this.counter++;
}
}
}
this is the union method:
public Set union (Set setToUnion) {
Set setToReturn;
if (this.equals(setToUnion)){
setToReturn = new Set(setToUnion);
return setToReturn;
}
setToReturn = new Set(this.set);
for (int i = 0; i < setToUnion.counter; i++) {
if (!setToReturn.isMember(setToUnion.set[i])) {
setToReturn.set[setToReturn.counter ] = setToUnion.set[i];
setToReturn.counter++;
}
}
return setToReturn;
}
and if you want to see how the isMember looks so here it is(just checking if some number is a member of other set):
public boolean isMember (int n) {
if (isEmpty()) {
return false;
}
for (int i = 0; i < this.counter; i++) {
if (n == this.set[i]) {
return true;
}
}
return false;
}
Now in the program I created two sets like this:
Set someSet = new Set(1,2,3,4,5);
Set anotherSet = new Set(2,6,7,8,9);
Set m = someSet.union(anotherSet);
m.show();
but the output I'm getting is (1,2,3,4,5,0,6,7,8,9) and i need the same one but without the 0 in the middle...
please help
thanks!

The problem appears to be this line in the union method:
setToReturn = new Set(this.set);
It should probably be:
setToReturn = new Set(this);
Why is that causing a problem?
At this point, this.set equals [1, 2, 3, 4, 5, 0, 0, 0, 0, 0], which is an int array. Therefore, the following constructor will be called:
public Set (int...numbers) { ... }
That means all those numbers in the array will be added, including the zeroes. Either you need to truncate the zeroes from the array by doing something like...
setToReturn = new Set( Arrays.copyOf( set, counter ) );
or have a constructor that accepts a Set. That way you can access counter to see how many numbers in the array are actually part of the Set. I guessed you already have that constructor, based on another part of the code that calls such a constructor.

Related

check if array is alrdeady FULLY filled with any non-default value

I am not sure if it's rly possible to check but I have an issue rn where I have an array
let's say: int[] unmarkedSum = new int[100];
Now I put something in this array when a certain condition is true so not in every single iteration. But I know for a fact that at some point the whole array will be filled with any positive values that are not 0 because of how my algorithm works.
My question here is: Is there a way of checking WHEN it's fully filled?
Like I started like this:
for(int i = 0; i < unmarkedSum.length; i++) {
if(unmarkedSum[i] == 0 {
break;
}
else {
// idk tbh
}
}
In Java by default an array of ints is filled with zeros. You can use this to check if the array is fully filled. For example you can create a method which checks for 0 and returns true if there are no 0:
public static bool isArrayFilled(int[] array) {
for(int i = array.length; i >= 0; i--){
if(array[i] == 0) {
return false;
}
}
return true;
}
If array is big enough and filled out of order, you can use advanced algorithms to find at least one 0 value in the array.
I would simply maintain a variable size that keep tracks of how many values have been written to the array.
Example:
int size = 0;
int[] array = new int[100];
Random r = new Random();
while(size < array.length){
int index = r.nextInt(100);
int val = r.nextInt(1000)+500;
if (array[index] == 0){
array[index] = val;
size++;
}
}
System.out.println(Arrays.toString(array));
Per my previous comment, you can share this array with another thread so that one thread can fill the values and another can check the array at the same time. When the second thread finds that there are no default values (or 0s) then it can notify the first thread (or the main thread). Here is how you can do that
import java.util.Arrays;
import java.util.Random;
public class CheckArray {
public static void main(String[] args) throws InterruptedException {
var arr = new int[50];
Thread arrayChecker = new Thread(() -> {
var isZeroPresent = false;
while (true) {
for (int index = 0; index < arr.length; index++) {
isZeroPresent = false;
if (arr[index] == 0) {
isZeroPresent = true;
break;
}
}
if (isZeroPresent == false) {
// if the for loop completed then control will come here
System.out.println("Array has been filled");
System.out.println(Arrays.toString(arr));
System.exit(0);
}
}
});
arrayChecker.start();
// fill random values in the array
// while another thread has been started
Random random = new Random();
while(true) {
Thread.sleep(500);
int index = random.nextInt(arr.length);
arr[index] = random.nextInt(100);
System.out.println(Arrays.toString(arr));
}
}
}

Compare elements of each row in a 2D matrix java

I was trying to compare the values of each element in a row of a 2D matrix to make sure every element is different from each other.
Here's my function:
private static boolean CompareComponentValue(int[][] m) {
int k = 0;
for (int i = 0; i < m.length; i = i + 1) {
for (int j = 1; j < m[i].length; j = j + 1) {
if (m[i][k] == m[i][j]) {
return false;
}
}
k = k + 1;
}
return true;
}
I was thinking that I had to campare each element like this: [0][0] is different from [0][1], [0][2] ...[0][n], then: [0][1] is different from [0][2]...[0][n] and also for each row of course, [1][0] is different from [1][1], [1][2]...[1][n].
I can't get it to work properly because it will return false sometimes when it shouldn't.
First of all thank you guys for your answers but they really went above my level, as I've stated at the beggining I'm not using any packages for now because I'm still a beeginer and I want to stay with basic logic and in the end I got an answer by thinking hard.
private static boolean NumerosDistintosFila(int[][] m) {
for (int i = 0; i < m.length; i = i + 1) {
for (int k = 0; k < m.length - 2; k = k + 1) {
for (int j = 1 + k; j < m[i].length; j = j + 1) {
if (m[i][k] == m[i][j]) {
return false;
}
}
}
}
return true;
}
I added another for loop with a variable k which I noticed didn't ever go above the matrix's lenght - 2, for example if I were to use a 5x5 I'll need it to go as far as 3.
This is because the last element I need to compare in the first row for example is [0][3] to [0][4].
My logic was that I needed to compare elements without repeating the comparations between them so what this code does is basically compare the first element with every element in the same row, then compare the second element with every element except the first one then the third element with the fourth and the fifth etc..
Again thank you guys for your solutions I tried them out and all of them worked perfectly but as I said I want to stay with basic logic for now.
A simple way is to create a Set out of each row and compare its size with the size of the row. A Set automatically discards duplicate values and therefore if the size of the Set is equal to the size of the row, all the elements in the row are unique.
Demo:
import java.io.IOException;
import java.util.Arrays;
import java.util.Set;
import java.util.stream.Collectors;
public class Solution {
public static void main(String[] args) throws IOException {
Integer n[][] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
Integer x[][] = { { 1, 2, 2 }, { 4, 5, 6 }, { 7, 8, 9 } };
System.out.println(compareComponentValue(n));
System.out.println(compareComponentValue(x));
}
private static boolean compareComponentValue(Integer[][] m) {
for (int i = 0; i < m.length; i++) {
// Add the row i.e. m[i] to a Set
Set<Integer> set = Arrays.stream(m[i]).collect(Collectors.toSet());
// If there will be any duplicate values in m[i], they will be rejected by the
// set and therefore the size of the set won't be equal to the size of m[i]
if (set.size() != m[i].length)
return false;
}
return true;
}
}
Output:
true
false
"... to make sure every element is different from each other."
What you need is a Set. Adding an element to a set, and testing whether an element is in the set already, are easy to do using the add and contains operations. Also, these operations both take O(1) time, so the solution will be efficient; no need to search the matrix again and again.
Also, use the "enhanced for loop" if you just need the values, not the indices.
import java.util.*;
public class CheckMatrix {
public static boolean hasDuplicate(int[][] matrix) {
Set<Integer> seen = new HashSet<>();
for(int[] row : matrix) {
// empty the set, to only check for duplicates within a single row
seen.clear();
for(int x : row) {
if(seen.contains(x)) { return true; }
seen.add(x);
}
}
return false;
}
}
If you want to be fancy, you can use the fact that the add method returns a boolean indicating whether x was not already present: replace the inner loop body with:
if(!seen.add(x)) { return true; }

How to check the object of type int[] of an arraylist?

I'm trying to find out particular elements in my ArrayList (arrayOne). Each element should be an int[]. I've tried System.out.println(arrayOne), which compiles but gives a irregular and strange number "[[I#370968]".
I've also tried System.out.println(arrayOne[0]) but it won't compile and emits the error
Array required but java.util.ArrayList found.
Given is the following code, with {1,12,3,13,123,2} passed to eg:
import java.util.ArrayList;
public class arrayTest {
private ArrayList<int[]> arrayOne;
public arrayTest(int[] eg) {
int[] xy = new int[2];
arrayOne = new ArrayList<int[]>(eg.length);
for (int i = 0; i < eg.length; i++) {
int sv = String.valueOf(eg[i]).length();
if (sv == 1) {
xy[0] = 0;
xy[1] = eg[i];
arrayOne.add(xy);
}
else if (sv == 2) {
System.out.println("two digits");
// TODO add code to make xy[0] = the first
// digit of eg and xy[1] = the second digit
}
else {
System.out.println("too many digits");
// and throw error accordingly
}
System.out.println(arrayOne);
}
}
}
How do make sure and print out the int array at arrayOne[0]
Given the code above if (sv == 2) and i want to split each individual number into an int[] with [0] being the first digit and [1] being the second digit how would i get the int value of each individual digit.
Use Arrays.toString(yourArray); to print out arrays in human readable form.
First of all, the string [I#370968 is displayed because you are trying to print an int[], which is actually an object. Because this object does not override the object's toString() method, that method is derived from the Object class. The Object.toString() implementation, which prints the class name (in this case [I, because it is an int array), then an # sign, and then the hash code of the object.
Your ArrayList contains a number of int[]s. Because an ArrayList is not an array (the one with the square brackets, like int[]), you can't call an element on it as if it were an array. In short, you cannot call arrayOne[someDesiredIndex].
In order to get an element from the ArrayList, call get(int index) on it; it returns the desired int[]. As already pointed out by another answer, you can use Arrays.toString(int[]) to print it in a human readable form.
To answer your questions:
You can retrieve the first index (0) of the first array inside arrayOne with the following code: arrayOne.get(0)[0].
The following code should work:
private static int[] intToArray(int n) {
String str = String.valueOf(n);
int length = str.length();
int[] ints = new int[length];
for (int i = 0; i < length; i++) {
ints[i] = Integer.parseInt(str.substring(i, i + 1));
}
return ints;
}
Above method puts each digit into the next array position (it also works with digits greater than 99). With this method you can easily get each individual digit:
int[] digits = intToArray(47);
int a = digits[0]; // Will be 4
int b = digits[1]; // Will be 7
So this is the class rewritten:
public class Rewrite {
private ArrayList<int[]> arrayOne = new ArrayList<int[]>();
public Rewrite(int[] eg) {
for (int i = 0; i < eg.length; i++) {
int length = String.valueOf(eg[i]).length();
switch (length) {
case 1:
this.arrayOne.add(new int[] { 0, eg[i] });
break;
case 2:
this.arrayOne.add(intToArray(eg[i]));
break;
default:
throw new IllegalArgumentException("Number " + eg[i] + " has too many digits");
// Or display the error or something.
}
System.out.println(Arrays.toString(this.arrayOne.get(i)));
}
}
private static int[] intToArray(int n) {
String str = String.valueOf(n);
int length = str.length();
int[] ints = new int[length];
for (int i = 0; i < length; i++) {
ints[i] = Integer.parseInt(str.substring(i, i + 1));
}
return ints;
}
public static void main(String[] args) {
Rewrite r = new Rewrite(new int[] { 47, 53, 91, 8 });
}

Getting NullPointerException in when array's size is not instantly assigned

I'm trying to learn Java and I am currently writing a program that will split an array of integers into two sub-arrays, one containing the positive values and the other the negative values.
Due to the fact that the sizes of the two sub-arrays can not be specified from the start (because this program should work on any array of integers) I wrote two methods which will calculate the sizes of the two sub-arrays (maxNeg and maxPos). Afterwards, the two sub-arrays (arrayNegative and arrayPositive) are initialized having the the two corresponding sizes.
The problem is that, when I try to populate the two arrays using the arraySorter(), the compiler gives me the ArrayIndexOutOfBoundsException: 0 error right at the first iteration inside the arraySorter() method.
Note 1: The issue doesn't occur when values are assigned to the maxNeg and maxPos variables from the start.
Note 2: I know this type of problem is usually solved using ArrayLists for storing the positives and negatives, but my assignment's requirements force me to do this using only arrays.
public class sortMethod {
public int max; // max = main array length
public int maxNeg; // the length of the final array that will store the
// negative integers
public int maxPos; // the length of the final array that will store the
// positive integers
public int[] intArray = new int[max];
public int getMaxNeg() {
for (int i = 0; i < max; i++) {
if (intArray[i] < 0) {
maxNeg++;
}
}
return maxNeg;
}
public int getMaxPos() {
for (int i = 0; i < max; i++) {
if (intArray[i] >= 0) {
maxPos++;
}
}
return maxPos;
}
public int[] negativeArray = new int[maxNeg];
public int[] positiveArray = new int[maxPos];
public int negIndex = 0;
public int posIndex = 0;
public void arraySorter() {
for (int a = 0; a < max; a++) {
if (intArray[a] < 0) {
negativeArray[negIndex] = intArray[a];
negIndex++;
// System.out.println(negativeArray[0]);
} else {
positiveArray[posIndex] = intArray[a];
posIndex++;
}
}
}
public sortMethod(int[] y, int z) {
this.intArray = y;
this.max = z;
}
Can someone explain why I'm keep getting the NullPointerException when using formulas to calculate the sizes of the two sub-arrays and why I don't get the error when values are assigned to 2 variables upon declaring them.
This is the main method where I created the test object:
public class ArraySort {
public static void main(String[] args) {
int[] array = { -12, 23, -22, 0, 43, -545, -4, -55, -43, -12, 0, -999};
int z = array.length;
sortMethod arrayTest = new sortMethod(array, z);
arrayTest.getMaxNeg();
arrayTest.getMaxPos();
arrayTest.arraySorter();
}
Thanks and please excuse me if my question's formating is not compliant with the site's standards, it's my first and I will try to improve in the future.
When this code is executed
public int[] negativeArray = new int[maxNeg];
public int[] positiveArray = new int[maxPos];
maxNeg and maxPos is equal to 0, so it is normal to have an out of bound exception.
To get it to works, you could initialize the arrays directly in the method so your code would become :
public int[] negativeArray;
public int[] positiveArray;
public int negIndex = 0;
public int posIndex = 0;
public void arraySorter() {
negativeArray = new int[maxNeg];
positiveArray = new int[maxPos];
for (int a = 0; a < max; a++) {
if (intArray[a] < 0) {
negativeArray[negIndex] = intArray[a];
negIndex++;
} else {
positiveArray[posIndex] = intArray[a];
posIndex++;
}
}
}
Another part of your code that is wrong is the constructor of sortMethod. You give the array length to the maximum bound, but the maximum bound is actually length - 1. so change this.max = z; to this.max = z - 1; 
Also, your algorithm does not sort numbers, it simply separate negatives of positives... If you want to sort an array of number you can simplify it in one line :
Arrays.sort(array);
The order in which you define variables and methods in Java is not important. Your instance variables (e.g. your negativeArray and positiveArray) are created as soon as the class instance is created (and before the constructor is called). You therefore initialize both arrays with a size of 0.

How to generate sums of combinations of elements of a set efficiently in terms of time and memory?

I have a random set S of integers and the cardinality (n) of this set may vary from 10 to 1000. I need to store all sums of the nCr combinations of size r generated from this set. Usually r range from 3 to 10.
E.g. if S={102,233,344,442,544,613,71289,836,97657,12} and r=4, Then The sums generated will be {0,1,2,3}=102+233+344+442, {0,1,2,4}=102+233+344+544,....so on.
I implemented a findCombi function (below) in Java which gave me all nCr combinations in terms of r sized sets of indices and then I sifted through these sets in another function to generate the sum of corresponding elements.
But the program is giving heapspace error, probably because of exponential nature and I have 100-5000 of such sets, S. Or may be there is a memory leak?
Is there a faster and lesser-memory consuming way to do it?
Note: dsize=n, combiSize=r
List <List<Integer>> findCombi(int dsize,int combiSize) {
if( (combiSize==0) || (dsize==0) ){
return null;
}
long n=dsize;
int r=combiSize;
for(int i=1;i<combiSize;i++) {
n=n*(dsize-i);
r=r*i;
}
int totalcombi=(int) n/r;
List <List<Integer>> combiData=new ArrayList<>(totalcombi);
int pos;
List <Integer> combi=new ArrayList<>(combiSize);
for(int i=0;i<combiSize;i++) {
combi.add(i,i);
}
combiData.add(new ArrayList<>(combi));
pos=combiSize-1;
while(true) {
if(combi.get(pos)<(dsize-combiSize+pos)) {
combi.set(pos,combi.get(pos)+1);
if(pos==(combiSize-1)) {
combiData.add(new ArrayList<>(combi));
}
else {
combi.set(pos+1,combi.get(pos));
pos++;
}
}
else {
pos--;
}
if(pos==-1) {
break;
}
}
return combiData;
}
I needed something like that earlier, so here is some code adapted from the project I made back then. The method allSums builds a list of indices of size r, which is used to represent all the possible combinations. At each step, the current sum is added to the result set, then the next combination is generated. Since the results are put in a set, there is no way a result could appear twice. I included a main method so you can see it work. I hope this is clear, feel free to ask questions.
import java.util.*;
public class Program {
static private Set<Integer> allSums(List<Integer> values, int r) {
HashSet<Integer> res = new HashSet<>();
if ((values.isEmpty()) || r > values.size()) {
return res;
}
// build the list of indices
List<Integer> li = new ArrayList<>();
for (int i = 0; i < r; i++) {
li.add(i);
}
li.add(values.size()); // artificial last index : number of elements in set
while (true) {
// add the current sum to the result
int sum = 0;
for (int i = 0; i < r; i++) {
sum += values.get(li.get(i));
}
res.add(sum);
// move to the next combination
// first, find the last index that can be incremented
int i = r-1;
while ((i >= 0) && (li.get(i) == li.get(i+1)-1)) {
i--;
}
// was such an index found ?
if (i == -1) {
break; // if not, it's over
}
// increment the last index and set all the next indices to their initial value
li.set(i,li.get(i)+1);
for (int j = i+1; j < r; j++) {
li.set(j, li.get(j-1)+1);
}
}
return res;
}
public static void main(String[] args) {
List<Integer> values = new ArrayList<>();
values.add(10);
values.add(100);
values.add(1000);
values.add(10000);
values.add(100000);
Set<Integer> s = allSums(values, 3);
for (int i : s) {
System.out.println(i);
}
}
}

Categories