Copy part of two-dimensional array - java

So I have a matrix M1 that I build at the beginning of my method each method call (this is all done in a non-static environment). The issue is that, depending on an integer index, say n I want the matrix M2 (in method call #2 for example) to contain rows 1, 2... n of M1 (the number of rows that I need for M changes each method call, but the number of columns persist).
My method in pseudocode;
int myMethod(numRows, numColumns, n) {
Initialize M as matrix with dimensions(numRows, numColumns)
if (n > 0) {
**copy rows 1,2...,n from previous M matrix**
}
**do stuff with M**
return M[numRows][numColumns];
What is a smart way to accomplish this? I hope it's clear what I'm asking for. Something worth noting is that Mi can be 'taller' or 'shorter' (it's always exactly as 'wide') as Mj for i > j

Maybe return the array and pass the array as a parameter.
int[][] mymethod(int[][]oldArray, int noOfRows){
int[][] newArr;
if(noOfRows > 0){
//here copy from oldArray to new;
//sorry this is where I can't remember, you will have
//to do something to get column size maybe oldArray[0].length()
// but that may not work if each row has different length.
newArr = new int[noOfRows][];
for(int i=0; i < noOfRows; i++){
for(int j = 0; j < noOfRows; j++){
newArr[i][j] = oldArray[i][j];
}
}
}
return newArr;
}
after this just call the method.
int [][] a = mymethod(dArray,5);
int [][] b = mymethod(a, 2);

You could use a two dimensional vector, and then perhaps the clone() method. The awesome thing about vector is that it can grow and shrink as you need it to.

Related

Write a function called arraySum that returns the sum (as an int) of all the values in a two-dimensional array of int values (Java)

I am trying to sum all the int values of a 2D array. I named it array. my function is then called arraySum. If arraySum is null, I return 0. Otherwise, it goes through two for-loops, summing the values of these arrays.
int i = 0;
int j = 0;
static int sum = 0;
int[][] array = new int[i][j];
static int arraySum(int[][] array) {
if (array == null) { // test if the incoming param is null
return 0;
} else {
for (int i = 0; i < array.length; i++) { // length of the outer array
for (int j = 0; j < array[i].length; j++) { // length of the inner array
sum += array[i][j];
}
}
return sum; // moved out of the loop
}
}
my error message:
java.lang.AssertionError: Incorrect result: expected [-217085] but found [-308126]
Fixing the method signature is the first step.
Then you'll need to fix the null check.
Then your loops need to check the size of the inner and outer arrays.
Move the return statement.
Here's the fixed code:
static int arraySum(int[][] array) { // fix the signature
if (array == null) { // test if the incoming param is null
return 0;
} else {
int sum = 0; // you need this in the scope of the method - it will be returned at the end
for (int i = 0; i < array.length; i++) { // length of the outer array
for (int j = 0; j < array[i].length; j++) { // length of the inner array
sum += array[i][j];
}
}
return sum; // moved out of the loop
}
}
Edit: I've concentrated on just the method now - how you call it is up to you. Please note that the method will not affect any externally defined sum variable. It will return the sum and it's up to the caller to store that value somewhere.
Avoid using primitive for statement. See following:
static int arraySum(int[][] array) {
int sum = 0;
if (array == null) return 0;
for(int[] row: array){
for(int col : row) {
sum += col;
}
}
return sum;
}
Streams can do this too:
//Create 2D array
int[][] array = {{1,2,3},{4,5},{6}};
//Sum all elements of array
int sum = Stream.of(array).flatMapToInt(IntStream::of).sum();
System.out.println(sum);
Picking apart the summing code:
Stream.of(array)
Turns the 2D array of type int[][] into a Stream<int[]>. From here, we need to go one level deeper to process each child array in the 2D array as the stream only streams the first dimension.
So at this point we'll have a stream that contains:
an int[] array containing {1,2,3}
an int[] array containing {4,5}
an int[] array containing {6}
.flatMapToInt(IntStream::of)
So far we have a Stream of int[], still two-dimensional. Flat map flattens the structure into a single stream of ints.
flatMapToInt() expands each int[] element of the stream into one or more int values. IntStream.of() takes an array int[] and turns it into an int stream. Combining these two gives a single stream of int values.
After the flattening, we'll have an int stream of:
{1,2,3,4,5,6}
.sum()
Now we have an IntStream with all elements expanded out from the original 2D array, this simply gets the sum of all the values.
Now the disclaimer - if you are new to Java and learning about arrays, this might be a little too advanced. I'd recommend learning about nesting for-loops and iterating over arrays. But it's also useful to know when an API can do a lot of the work for you.

How to copy a 2-dimensional array in java

I just began studying java. One of the tasks was to create a function to create a reverse 2-dimensional array, for example, if the input array was {1,2}{3,4}, the new array must be {4,3}{2,1}. The code below is the method I created. The problem is that the old array d is affected by the loop along with c, so, in this case, it copies half of the values into c, but also replaces the last half of d, so the second half of c is just a mirrored first half, basically, in the example case both c and d will be like this in the end: {4,3}{3,4}. I checked c==d and c.equals(d) after cloning, both show false.
Also, I tried using Arrays.copy, the result was the same. Plus I want the method to work on the arrays that can have their sub-arrays with different lengths, for example, {1,2}{3}{4,5}, and I don't know if it'll work on such arrays.
static int[][] reversematrix(int[][] d) {
int[][] c = d.clone();
for (int i = d.length-1, x = 0; i >= 0; x++, i--) {
for (int j = d[i].length-1, y = 0; j>=0; y++, j--) {
c[x][y] = d[i][j];
}
}
return c;
Can you tell me how to make d(imput array) unaffected by the method/loop? I think the problem is in copying, so I'd love to know a proper way of copying a 2D array into a new object, but if it is in something else, please tell me waht it is.
UPD: Thanks to #sascha the solution was found. Here's the code if someone is interested:
static int[][] reversematrix(int[][] d) {
int[][] c = new int[d.length][];
for (int i = d.length-1, x = 0; i >= 0; x++, i--) {
c[x] = new int[d[i].length];
for (int j = d[i].length-1, y = 0; j>=0; y++, j--) {
c[x][y] = d[i][j];
}
}
return c;
}

Iterating a 2D Array using Java 8

This is an implementation of the 0-1 Knapsack Problem. The problem statement goes like this,
You're given two arrays, one containing the weights of a set of items and the other containing values for the respective weights. You're provided a max weight. Within the constraint of staying under the max weight, determine the maximum value that you can obtain by selecting or not selecting the set of items.
The values and the weight list will always be of the same size.
This is my solution, which generally works fine(not on edge cases).
public static int getCombination(int[] weights, int[] values, int maxWeight){
int[][] memo = new int[weights.length][maxWeight + 1];
for (int i = 0; i < memo.length; i++) {
for(int j=0; j < memo[i].length; j++){
if(j == 0){
memo[i][j] = 0;
}else if(weights[i] > j){
if(i == 0) memo[i][j] = 0;
else memo[i][j] = memo[i-1][j];
}else{
if(i == 0){
memo[i][j] = values[i];
}
else{
memo[i][j] = Integer.max((values[i] + memo[i-1][j- weights[i]]), memo[i-1][j]);
}
}
}
}
return memo[weights.length -1][maxWeight];
}
Now I want to re-write this complete logic in a declarative manner using Java 8 Streams and lambdas. Can someone help me with that.
Since your for loop based solution is completely fine, streams do not add much value here if you only convert the for loops to forEach streams.
You get more out of using streams, if you use IntStream and the toArray method, because you can concentrate on calculating the value based on row and column index, and not care about filling it into the array.
int[][] memo = IntStream.range(0, rows)
.mapToObj(r -> IntStream.range(0, cols)
.map(c -> computeValue(r, c))
.toArray())
.toArray(int[rows][cols]::new);
Here, we create an array for each row, and then put those into a 2D-array at the end. As you can see, the toArray() methods take care of filling the arrays.
Actually, now that I looked at your method to calculate the values more closely, I realize that streams might be difficult if not impossible to use in this case. The problem is that you need values from previous columns and rows to calculate the current value. This is not possible in my solution precisely because we only create the arrays at the end. More specifically, my approach is stateless, i.e. you do not remember the result of previous iterations.
You could see if you can use Stream.reduce() to achieve your goal instead.
BTW, your approach is fine. If you don't want to parallelize this, you are good to go.
Here's a possible starting point to create the indices into your array:
int rows = 3;
int cols = 4;
int[][] memo = new int[rows][cols];
IntStream.range(0, rows * cols).forEach(n -> {
int i = n / cols;
int j = n % cols;
System.out.println("(" + i + "," + j + ")");
});

Two sum - Doesn't work

Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.
Consider input [3,2,4] and target is 6. I added (3,0) and (2,1) to the map and when I come to 4 and calculate value as 6 - 4 as 2 and when I check if 2 is a key present in map or not, it does not go in if loop.
I should get output as [1,2] which are the indices for 2 and 4 respectively
public int[] twoSum(int[] nums, int target) {
int len = nums.length;
int[] arr = new int[2];
Map<Integer,Integer> map = new HashMap<Integer,Integer>();
for(int i = 0;i < len; i++)
{
int value = nums[i] - target;
if(map.containsKey(value))
{
System.out.println("Hello");
arr[0] = value;
arr[1] = map.get(value);
return arr;
}
else
{
map.put(nums[i],i);
}
}
return null;
}
I don't get where the problem is, please help me out
Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have exactly one solution, and you may not use the same element twice. Consider input [3,2,4] and target is 6. I added (3,0) and (2,1) to the map and when I come to 4 and calculate value as 6 - 4 as 2 and when I check if 2 is a key present in map or not, it does not go in if loop.
Okay, let's take a step back for a second.
You have a list of values, [3,2,4]. You need to know which two will add up 6, well, by looking at it we know that the answer should be [1,2] (values 2 and 4)
The question now is, how do you do that programmatically
The solution is (to be honest), very simple, you need two loops, this allows you to compare each element in the list with every other element in the list
for (int outter = 0; outter < values.length; outter++) {
int outterValue = values[outter];
for (int inner = 0; inner < values.length; inner++) {
if (inner != outter) { // Don't want to compare the same index
int innerValue = values[inner];
if (innerValue + outterValue == targetValue) {
// The outter and inner indices now form the answer
}
}
}
}
While not highly efficient (yes, it would be easy to optimise the inner loop, but given the OP's current attempt, I forewent it), this is VERY simple example of how you might achieve what is actually a very common problem
int value = nums[i] - target;
Your subtraction is backwards, as nums[i] is probably smaller than target. So value is getting set to a negative number. The following would be better:
int value = target - nums[i];
(Fixing this won't fix your whole program, but it explains why you're getting the behavior that you are.)
This code for twoSum might help you. For the inputs of integer array, it will return the indices of the array if the sum of the values = target.
public static int[] twoSum(int[] nums, int target) {
int[] indices = new int[2];
outerloop:
for(int i = 0; i < nums.length; i++){
for(int j = 0; j < nums.length; j++){
if((nums[i]+nums[j]) == target){
indices[0] = i;
indices[1] = j;
break outerloop;
}
}
}
return indices;
}
You can call the function using
int[] num = {1,2,3};
int[] out = twoSum(num,4);
System.out.println(out[0]);
System.out.println(out[1]);
Output:
0
2
You should update the way you compute for the value as follows:
int value = target - nums[i];
You can also check this video if you want to better visualize it. It includes Brute force and Linear approach:

Transposing Values in Java 2D ArrayList

Good evening all,
I'm trying to write a method that creates and returns a 2D array whose elements in each location are the same as the elements in the mirror image location of the parameter array. Unfortunately, no matter what pair of numbers I enter into the method call I get an "out of bounds" error in my compiler. Below is my program. Tell me where I've gone wrong! Thanks!
public static int[][] transpose(int [][] a) {
int r = a.length;
int c = a[r].length;
int [][] t = new int[c][r];
for(int i = 0; i < r; ++i) {
for(int j = 0; j < c; ++j) {
t[j][i] = a[i][j];
}
}
return t;
}
}
Arrays in java are 0 based, change your assignment to c to :
int c = a[r - 1].length;
#Suraj is correct, however you must assume the 2D array is rectangular, in which case it is sightly more efficient to change line 3 to:
int c = a[0].length;
#Kris answer text is correct however code sample is wrong line.
Note this error is a reproduction of a broken "answer" posted in "Yahoo Answers": http://answers.yahoo.com/question/index?qid=20080121204551AAn62RO
Your problem lies in line two: a[r].length returns the number of columns, but arrays are indexed from 0. You should adjust accordingly:
int r = a.length - 1;

Categories

Resources