Related
To begin, I am doing this using only arrays (no hash maps or array lists).
I am trying to create a method, project, which inputs two integer arrays with different sizes.
I am trying to compare them in a way to get the following output: projecting [1, 3, 5, 3] to [2, 1, 6, 3, 1, 4, 5, 3] results in: [1, 3, 1, 5, 3].
However, projecting [2, 1, 6, 3, 1, 4, 5, 3] to [1, 3, 5, 3] results in: [1, 3, 5, 3].
I believe the nested for loop might be wrong as it is iterating through the first indices for the first array all the way through the second array, then going to the next.
I'm getting an ArrayIndexOutOfBoundsException for the starred line (tempArray[i] == arr1[i], I know it shouldn't be tempArray[i] but not sure what exactly to put).
I'm not sure how to compare them in a way to produce the line above, as it needs to be "in order". What could be the best way to accomplish this?
I attempted the following code:
public int[] project(int[] arr1, int[] arr2) {
int counter = 0;
for (int i = 0; i < arr1.length; i++) {
for (int j = 0; j < arr2.length; j++) {
if (arr1[i] == arr2[j]) {
counter++;
}
}
}
int[] tempArray = new int[counter];
for(int i = 0 ; i < arr1.length; i++) {
for (int j = 0; j < arr2.length; j++) {
if(arr1[i] == arr2[j]) {
tempArray[i] = arr1[i]; // UNDERLINED
}
}
}
}
Edit
The ArrayIndexOutOfBounds error is gone, but now my return statement is: projecting [1, 3, 5] to [2, 1, 6, 3, 1, 4, 5, 3] results in: [1, 3, 5, 0, 0], when it needs to be: projecting [1, 3, 5] to [2, 1, 6, 3, 1, 4, 5, 3] results in: [1, 3, 1, 5, 3].
Any idea what is causing this issue?
I think you have a typo in your first for loop
change this to later
arr1[i] == arr2[i]
to
arr1[i] == arr2[j]
Regarding overlapping issues in the projection array, you need to maintain different value as your index rather than i or j which is used by arr1 and arr2 respectively
int[] tempArray = new int[counter];
int index = 0;
for(int i=0 ; i < arr1.length; i++) {
for (int j=0; j < arr2.length; j++) {
if(arr1[i] == arr2[j]) {
tempArray[index++] = arr1[i];
}
}
}
For the values which you are expecting you should loop through arr2 first
for(int j=0 ; j < arr2.length; j++) {
for (int i=0; i < arr1.length; i++) {
if(arr1[i] == arr2[j]) {
tempArray[index++] = arr1[i];
}
}
}
If the contents of array are not hardcoded and you dont know the order in which you want to pass, you can make use of length
int[] ans;
if(a.length < b.length) {
ans = project(a, b);
} else {
ans = project(b, a);
}
Output:
[1, 3, 1, 5, 3]
You currently have index variables (i, j) tracking the indexes of each input array as you loop through them, but you also need to keep track of the write head of the result array. Initialize, say int k = 0 before the outer for loop, then set the value like this: tempArray[k++] = array1[i];.
You can forgo the first loop If you are OK with performing a single array copy. Initialize an array as long as the second input array (since there can never be more duplicated elements than existing elements) as the tempArray. Then if you want it to fit exactly, initialize the final array to the exact length k and use System#arrayCopy.
this will probably solve your problem
public int[] project(int[] arr1, int[] arr2) {
int counter = 0;
for (int i : arr2) {
if (Arrays.binarySearch(arr1, i) >= 0) {
counter++;
}
}
int[] arr4 = new int[counter];
int index = 0;
for (int i : arr2) {
if (Arrays.binarySearch(arr1, i) >= 0) {
arr4[index++] = i;
}
}
return arr4;
}
The nested iteration is expensive, so we want to avoid that. The first thing to do is sort the array we are projecting from so we can perform a binary search on it. Second, don't execute the nested iteration to determine the output array size. Create an array the size of the array we are projecting to since it can be no longer than that.
public int[] projection(int[] a, int[] b) {
int[] temp = new int[b.length];
int nextIndex = 0;
for (int x : b) {
if (contains(a, x)) {
temp[nextIndex++] = x;
}
}
return slice(temp, nextIndex);
}
private boolean contains(int[] array, int value) {
for (int element : array) {
if (element == value) {
return true;
}
}
return false;
}
private int[] slice(int[] src, int size) {
int[] slice = new int[size];
for (int index = 0 ; index < size ; ++index) {
slice[index] = src[index];
}
return slice;
}
For your second problem, I think, in your temporary array, you should be saving the values from arr2[j] instead of arr1[i].
Also, you need a different counter (set to 0 initially and incremented in the loop) for setting the values in tempArray[counter].
What I mean exactly is:
int counter = 0;
for (int i = 0; i < arr1.length; i++) {
for (int j = 0; j < arr2.length; j++) {
if (arr1[i] == arr2[j]) {
tempArray[counter] = arr2[j];
counter++;
}
}
}
I'm trying to write a method, union(), that will return an int array, and it takes two int array parameters and check if they are sets, or in other words have duplicates between them. I wrote another method, isSet(), it takes one array argument and check if the array is a set. The problem is I want to check if the two arrays in the union method have duplicates between them, if they do, I want to extract one of the duplicates and put it in the unionArray[] int array. This is what I tried so far.
public int[] union(int[] array1, int[] array2){
int count = 0;
if (isSet(array1) && isSet(array2)){
for (int i = 0; i < array1.length; i++){
for (int j = 0; j < array2.length; j++){
if (array1[i] == array2[j]){
System.out.println(array2[j]);
count ++;
}
}
}
}
int[] array3 = new int[array2.length - count];
int[] unionArray = new int[array1.length + array3.length];
int elementOfUnion = 0;
for (int i = 0; i< array1.length; i++){
unionArray[i] = array1[i];
elementOfUnion = i + 1 ;
}
int index = 0;
for (int i = elementOfUnion; i < unionArray.length; i++){
unionArray[i] = array3[index];
index++;
}
return unionArray;
}
public boolean isSet(int[] array){
boolean duplicates = true;
for (int i = 0; i < array.length; i++){
for(int n = i+1; n < array.length; n++){
if (array[i] == array[n])
duplicates = false;
}
}
return duplicates;
}
What I was trying to do is to use all of array1 elements in the unionArray, check if array2 has any duplicates with array1, and then move all the non-duplicate elements from array2 to a new array3, and concatenate array3 to unionArray.
It will be much easier to do it with Collection API or Stream API. However, you have mentioned that you want to do it purely using arrays and without importing any class, it will require a few lengthy (although simple) processing units. The most important theories that drive the logic is how (given below) a union is calculated:
n(A U B) = n(A) + n(B) - n(A ∩ B)
and
n(Only A) = n(A) - n(A ∩ B)
n(Only B) = n(B) - n(A ∩ B)
A high-level summary of this solution is depicted with the following diagram:
Rest of the logic has been very clearly mentioned through comments in the code itself.
public class Main {
public static void main(String[] args) {
// Test
display(union(new int[] { 1, 2, 3, 4 }, new int[] { 3, 4, 5, 6 }));
display(union(new int[] { 1, 2, 3 }, new int[] { 4, 5, 6 }));
display(union(new int[] { 1, 2, 3, 4 }, new int[] { 1, 2, 3, 4 }));
display(union(new int[] { 1, 2, 3, 4 }, new int[] { 3, 4 }));
display(union(new int[] { 1, 2, 3, 4 }, new int[] { 4, 5 }));
display(union(new int[] { 1, 2, 3, 4, 5, 6 }, new int[] { 7, 8 }));
}
public static int[] union(int[] array1, int[] array2) {
// Create an array of the length equal to that of the smaller of the two array
// parameters
int[] intersection = new int[array1.length <= array2.length ? array1.length : array2.length];
int count = 0;
// Put the duplicate elements into intersection[]
for (int i = 0; i < array1.length; i++) {
for (int j = 0; j < array2.length; j++) {
if (array1[i] == array2[j]) {
intersection[count++] = array1[i];
}
}
}
// Create int []union of the length as per the n(A U B) = n(A) + n(B) - n(A ∩ B)
int[] union = new int[array1.length + array2.length - count];
// Copy array1[] minus intersection[] into union[]
int lastIndex = copySourceOnly(array1, intersection, union, count, 0);
// Copy array2[] minus intersection[] into union[]
lastIndex = copySourceOnly(array2, intersection, union, count, lastIndex);
// Copy intersection[] into union[]
for (int i = 0; i < count; i++) {
union[lastIndex + i] = intersection[i];
}
return union;
}
static int copySourceOnly(int[] source, int[] exclude, int[] target, int count, int startWith) {
int j, lastIndex = startWith;
for (int i = 0; i < source.length; i++) {
// Check if source[i] is present in intersection[]
for (j = 0; j < count; j++) {
if (source[i] == exclude[j]) {
break;
}
}
// If j has reached count, it means `break;` was not executed i.e. source[i] is
// not present in intersection[]
if (j == count) {
target[lastIndex++] = source[i];
}
}
return lastIndex;
}
static void display(int arr[]) {
System.out.print("[");
for (int i = 0; i < arr.length; i++) {
System.out.print(i < arr.length - 1 ? arr[i] + ", " : arr[i]);
}
System.out.println("]");
}
}
Output:
[1, 2, 5, 6, 3, 4]
[1, 2, 3, 4, 5, 6]
[1, 2, 3, 4]
[1, 2, 3, 4]
[1, 2, 3, 5, 4]
[1, 2, 3, 4, 5, 6, 7, 8]
Using Java's streams could make this quite simpler:
public int[] union(int[] array1, int[] array2) {
return Stream.of(array1, array2).flatMapToInt(Arrays::stream).distinct().toArray();
}
Even with all the restrictions of only using arrays, you can simplify your code a lot. No need to check for sets. Just :
allocate an array to store all elements of the union (i.e., int[] tmp_union ), which at worst will be all elements from both arrays array1 and array2.
iterate over the elements of array1 and compared them against the elements from tmp_union array, add them into the tmp_union array only if they were not yet added to that array.
Repeat 2) for the array2.
During this process keep track of the number of elements added to the tmp_union array so far (i.e., added_so_far). In the end, copy the elements from the tmp_union array into a new array (i.e., unionArray) with space allocated just for the union elements. The code would look something like:
public static int[] union(int[] array1, int[] array2){
int[] tmp_union = new int[array1.length + array2.length];
int added_so_far = add_unique(array1, tmp_union, 0);
added_so_far = add_unique(array2, tmp_union, added_so_far);
return copyArray(tmp_union, added_so_far);
}
private static int[] copyArray(int[] ori, int size) {
int[] dest = new int[size];
for(int i = 0; i < size; i++)
dest[i] = ori[i];
return dest;
}
private static int add_unique(int[] array, int[] union, int added_so_far) {
for (int element : array)
if (!is_present(union, added_so_far, element))
union[added_so_far++] = element;
return added_so_far;
}
private static boolean is_present(int[] union, int added_so_far, int element) {
for (int z = 0; z < added_so_far; z++)
if (element == union[z])
return true;
return false;
}
I have a array that contains arrays in it.
and I need to write a function that sort the little array on the big array( I mean the minimum sum of the little array is be the first on the index 0 and after the second on index1 and the maximum sum of the little array in in the end of the big aray =index bigArray.length-1
How can I sort an array that contains arrays in it?
i need to do that with no object or things like that. just regular and simple code.
enter image description here
public static int [][] sum (int [][] arr) {
int sum=0;
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr.length; j++) {
sum=sum+arr[i][j];
}
Since summing the inner array is a relatively time-consuming process, and the sum value is needed more than once when sorting, you should create an object to hold the array and the sum, e.g.
static class ArraySum implements Comparable<ArraySum> {
final int[] array;
final int sum;
ArraySum(int[] array) {
this.array = array;
this.sum = Arrays.stream(array).sum();
}
#Override
public int compareTo(ArraySum that) {
return Integer.compare(this.sum, that.sum);
}
}
Since it's Comparable, you can sort it directly, so with that in hand, you can easily sort the outer array using Java 8+ streams:
public static int[][] sort(int[][] arr) {
return Arrays.stream(arr).map(ArraySum::new).sorted()
.map(a -> a.array).toArray(int[][]::new);
}
That doesn't sort the input 2D array, but returns a new 2D array, i.e. a new outer array with the original inner arrays sorted.
Test
int[][] arr = { { 3, 5, 4 }, { 4, 3, 1, 2 }, { 5, 6 } };
int[][] arr2 = sort(arr);
System.out.println(Arrays.deepToString(arr));
System.out.println(Arrays.deepToString(arr2));
Output
[[3, 5, 4], [4, 3, 1, 2], [5, 6]]
[[4, 3, 1, 2], [5, 6], [3, 5, 4]]
// 10 11 12 sum
As you can see, the original 2D array is unmodified, and the new array is sorted by the sum of the inner arrays.
I don't think this works perfectly, but it should definitely get you close. I believe this is a buble sort technique.
public static int [][] sum (int [][] arr) {
//start at first array
for (int i = 0; i < arr.length - 1; i++) {
//sum of first array
int sum1 = 0;
for (int j = 0; j < arr[i].length; j++){
sum1 += arr[i][j];
}
//compare to each of the arrays after
for (int k = i+1; k < arr.length; k++) {
int sum2 = 0;
for (int l = 0; l < arr[k].length; j++){
sum2 += arr[k][l];
}
//if second array is smaller, swap
if (sum2 < sum1){
//might need to change this part to do complete copy
temp = arr[i];
arr[i] = arr[k];
arr[k] = temp;
}
}
}
return arr
}
Looking at a for-each loop but don't know how to do it using regular for loop in Java as in:
for(int i=0; i<length;i++)
Change this for-each loop
for (int[] bomb: bombs) {
Tried this
`for (int[] bomb = 0; bomb<bombs; bomb++) // doesn't work
Clarification:
I know what these two loops mean
for (int[]bomb: bombs)`
for (int i = 0; i<bombs.length; i++){}
If possible, I want their combined functionality of saving the i position in 2D array and saving i as the array itself in one for loop line.
In other words, I want the convenience of having the loop position in 2D array and directly grabbing the int[] array in the 2D array.
Context
public class MS {
public static void main(String[] args) {
//Example of input
int[][] bombs2 = {{0, 0}, {0, 1}, {1, 2}};
// mineSweeper(bombs2, 3, 4) should return:
// [[-1, -1, 2, 1],
// [2, 3, -1, 1],
// [0, 1, 1, 1]]
}
public static int[][] mineSweeper(int[][] bombs, int numRows, int numCols) {
int[][] field = new int[numRows][numCols];
//////////////////////// Enhanced For Loop ////////////////////
for (int[] bomb: bombs) {
////////////////////// Change to regular for loop //////////////
int rowIndex = bomb[0];
int colIndex = bomb[1];
field[rowIndex][colIndex] = -1;
for(int i = rowIndex - 1; i < rowIndex + 2; i++) {
for (int j = colIndex - 1; j < colIndex + 2; j++) {
if (0 <= i && i < numRows &&
0 <= j && j < numCols &&
field[i][j] != -1) {
field[i][j] += 1;
}
}
}
}
return field;
}
}
As per The for Statement following two are the same:
for (int i = 0; i < bombs.length; i++) {
int[] bomb = bombs[i];
}
or
for (int[] bomb : bombs) {
}
Assuming that I understand your question,
just use two, nested for-each style loops;
one for the double array and one for each member of the double array.
Here is some example code:
public class LearnLoopity
{
private int[][] doubleListThing = {{0, 0}, {0, 1}, {1, 2}};
#Test
public void theTest()
{
System.out.print("{");
for (int[] singleListThing : doubleListThing)
{
System.out.print("{");
for (int individualValue : singleListThing)
{
System.out.print(individualValue + " ");
}
System.out.print("} ");
}
System.out.print("} ");
}
}
I'm working on an assignment for a beginning Java course and I am completely stuck on this problem.
Write a program that computes the sum of the differences of pairs of numbers in an array. For example if the array is [2, 3, 7, 8, 9, 12] the sum of the differences of pairs is
(2-3) + (7-8) + (9-12)
** we are not allowed to use built in Java functions.
Here is what I have so far.. (I know it is terrible)
public static void main(String[] args)
{
int[] A = {3, 4, 5, 6, 1, 2};
int total = 0;
int sum = 0;
for(int i = 0; i < A.length; i++)
{
for(int j = i+1; j < A.length; j++)
sum = (A[i] - A[j]);
}
System.out.println(sum);
}
}
When you use that nested cycle you're doing this:
i = 0,
j = 1,
sum = 3 - 4;
// next cycle,
i = 0,
j = 2,
sum = 3 - 5;
// etc...,
i = 1,
j = 2,
sum = 4 - 5,
// etc..;
Which means for each value of A[i] you're making the difference of A[i] and all the values in the array for A[j + 1]. Also you're not updating the sum variable. When you do sum = A[i] - A[i + 1] because this operation only gives the variable sum a new value. What you want is sum+= value, which means sum = sum + newValue (newValue = A[i] - A[i +1]). This operation adds the new value to the old value stored in sum.
So what you need to do is add the two values and jump 2 indexes (i+=2) so you don't do (for example) 3-4, 4-5, 5-6 etc. what you want is 3-4, 5-6, etc.
Try this:
public static void main(String[] args)
{
int[] A = {3, 4, 5, 6, 1, 2};
int total = 0;
int sum = 0;
for(int i = 0; i < A.length; i+=2)
{
sum +=(A[i] - A[i + 1]);
}
System.out.println(sum);
}
}
I am not sure what are you stuck on exactly but looks like you are not adding the sum.
public static void main(String[] args)
{
int[] A = {3, 4, 5, 6, 1, 2};
int total = 0;
int sum = 0,i=0;
while(i<A.length){
sum+= (A[i] - A[i++]);
}
System.out.println(sum);
}