I'm having trouble with splitting up a vector into a 2D matrix or a given side. For example, given the vector {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}, the rows (3), and columns (4) can be turned into {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}}.
As of right now, the code just prints out the entire vector in a an array for however many rows their are.
int[][] reshape(int[] vector, int row, int col) {
if (!isReshapable(vector.length, row, col)) {
return null;
} else {
int[][] matrix = new int[row][col];
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
Arrays.fill(matrix, vector);
}
}
return matrix;
}
}
You're iterating both i and j. You could use them (and the position in the vector) with something like,
int p = 0;
int[][] matrix = new int[row][col];
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++, p++) {
matrix[i][j] = vector[p];
}
}
Related
I want to write a function that takes an 2d array and fills it with 1...n but counting the columns first instead of the rows:
input = {{0, 0, 0, 0}, {0}, {0}, {0, 0}};
the output should be: {{1, 5, 7, 8}, {2}, {3}, {4, 6}};
if i were to loop through rows and then colums i get:
private static void fill1(int[][] input) {
int count = 1;
for (int i = 0; i < input.length; i++) {
for (int j = 0; j < input[i].length; j++) {
input[i][j] = count;
count++;
}
}
}
How do I loop through colums first?
You can do this by first transposing your input, executing your fill1 code and then transposing the output again.
See this question for how to transpose a 2 dimensional array in Java: java multi-dimensional array transposing
If you were dealing with a regular 2d matrix, where all the rows had the same number of columns, the code would be a simple modification of the code for filling the matrix row-by-row:
private static void fill1(int[][] input) {
int count = 1;
for (int j = 0; j < input[0].length; j++) {
for (int i = 0; i < input.length; i++) {
input[i][j]= count;
count++;
}
}
}
The process is basically the same for a ragged 2d array, but with a couple added twists:
You need to do some extra work to figure out how many columns there could be (i.e., the maximum row length)
You need to be prepared for the case when there's no cell at a given row/column position.
The following modification of the previous code addresses these issues:
private static void fill1(int[][] input) {
int maxCols = input[0].length;
for (int i = 1; i < input.length; ++i) {
if (input[i].length > maxCols) {
maxCols = input[i].length;
}
}
int count = 1;
for (int j = 0; j < maxCols; j++) {
for (int i = 0; i < input.length; i++) {
if (j < input[i].length) {
input[i][j]= count;
count++;
}
}
}
}
To iterate first over the columns of a jagged 2d array to fill it, you have to know the maximum number of columns beforehand, but if you don't know that, you can iterate to the Integer.MAX_VALUE and check at each step if the columns are still present or not:
int[][] arr = {{0, 0, 0, 0}, {0}, {0}, {0, 0}};
int count = 1;
for (int col = 0; col < Integer.MAX_VALUE; col++) {
boolean max = true;
for (int row = 0; row < arr.length; row++) {
if (col < arr[row].length) {
arr[row][col] = count;
count++;
max = false;
}
}
if (max) break;
}
for (int[] row : arr) {
System.out.println(Arrays.toString(row));
}
Output:
[1, 5, 7, 8]
[2]
[3]
[4, 6]
See also: How do you rotate an array 90 degrees without using a storage array?
To populate a 2d array first by columns, you can use two nested streams. In case of a jagged 2d array, when you don't know beforehand the number of the columns in each row, in an outer stream you can traverse while the columns are still present.
/**
* #param arr array that should be populated.
* #return maximum row length, i.e. columns count.
*/
private static long populate(int[][] arr) {
AtomicInteger counter = new AtomicInteger(1);
return IntStream
// traverse through the array columns
.iterate(0, i -> i + 1)
// process the array rows where
// this column is present
.mapToLong(i -> Arrays.stream(arr)
// filter those rows where
// this column is present
.filter(row -> row.length > i)
// assign a value to the element and increase the counter
.peek(row -> row[i] = counter.getAndIncrement())
// count of rows where this column is present
.count())
// while the columns are still present
.takeWhile(i -> i > 0)
// max columns count
.count();
}
public static void main(String[] args) {
int[][] arr = {{0, 0, 0, 0, 0, 0}, {0, 0}, {0}, {0, 0, 0}};
System.out.println("Max columns count: " + populate(arr));
System.out.println(Arrays.deepToString(arr));
}
Output:
Max columns count: 6
[[1, 5, 8, 10, 11, 12], [2, 6], [3], [4, 7, 9]]
See also: How to create a new List from merging 3 ArrayLists in round robin style?
I think I am missing something fundamental here about Java, I am not sure why my code below do not work, my steps:
the input is a 2x2 matrix,
copy the original matrix,
loop through rows then column,
assign original matrix's column values to the rows of the transpose matrix.
static void transpose(int[][] matrix) {
int[][] temp = matrix.clone();
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
matrix[i][j] = temp[j][i];
}
}
}
The problem is use the function clone() because that will create a new matrix sharing only row arrays.
Using the same code style, that works:
int[][] temp = new int[2][2];
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
temp[i][j] = matrix[j][i];
}
}
Note that, as temp is an empty matrix, the comparsion will be temp = matrix.
So this works for a simple 2x2 matrix, but if you need other dimensions, instead of
int[][] temp = new int[2][2];
Use
int[][] temp = new int[matrix[0].length][matrix.length];
By the way, update the reference memory of the matrix is not a good practice. I think your method should return temp matrix.
An entire update, a better method could be this one. Is almost the same you have but it can accept diferent lengths.
public static int[][] transpose(int [][] matrix){
int[][] temp = new int[matrix[0].length][matrix.length];
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
temp[j][i] = matrix[i][j];
}
}
return temp;
}
You can use IntStream instead of for loop:
public static void main(String[] args) {
int[][] m1 = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}};
int[][] m2 = transpose(m1);
Arrays.stream(m2).map(Arrays::toString).forEach(System.out::println);
// [1, 4, 7]
// [2, 5, 8]
// [3, 6, 9]
}
static int[][] transpose(int[][] matrix) {
return IntStream.range(0, matrix.length).mapToObj(i ->
IntStream.range(0, matrix[i].length).map(j ->
matrix[j][i]).toArray())
.toArray(int[][]::new);
}
Basically i have to return an array of n numbers repeated in an array into another array of length m.
my code so far:
public class Histogram {
public static int[] frequency(int[] a, int M) {
int[] m = new int[M];
int count = 0;
for(int j = 0; j < a.length; j++)
for(int i = 0; i < m.length; i++)
if( i == a[j]){
m[i] = count++;
}
}
return m;
} public static void main(String[] args) {
int[] a = {7, 4, 9, 1, 10, 11, 11, 1, 5, 8, 4, 2, 9, 4, 3, 9,
2, 10, 11, 7, 7, 1, 11, 3, 8, 8, 10, 4, 10, 5};
int[] b = frequency(a, 12);
for (int i = 0; i < b.length; i++) {
Std.Out.println(i + "->" + b[i]);
} } }
this is the output im supposed to get
0->0
1->3
2->2
3->2
4->4
5->2
6->0
7->3
8->3
9->3
10->4
11->4
but im getting
0->0
1->21
2->16
3->23
4->27
5->29
6->0
7->20
8->25
9->15
10->28
11->22
what am i doing wrong?
I am not going to give you a different solution, but rather to show the mistakes in your code. If we go with the logic in your code, you have few mistakes:
1) count should be reset to 0 after first loop. Otherwise you will sum up the counts from the previous iterations.
2) count++ should be before the assignment, otherwise it will first assign and then increment. Or you could use ++count.
3) The first loop should be over i.
public static int[] frequency(int[] a, int M) {
int[] m = new int[M];
int count;
for(int i = 0; i < m.length; i++) {
count =0;
for(int j = 0; j < a.length; j++)
if( i == a[j]){
count++;
m[i] = count;
}
}
return m;
}
Regards.
This should solve it and do the job!
public class Histogram {
public static int[] frequency(int[] a, int M) {
int[] m = new int[M];
for(int j = 0; j < a.length; j++) {
m[a[j]] += 1;
}
return m;
}
public static void main(String[] args) {
int[] a = {7, 4, 9, 1, 10, 11, 11, 1, 5, 8, 4, 2, 9, 4, 3, 9,
2, 10, 11, 7, 7, 1, 11, 3, 8, 8, 10, 4, 10, 5};
int[] b = frequency(a, 12);
for (int i = 0; i < b.length; i++) {
System.out.println(i + "->" + b[i]);
}
}
}
public class Histogram {
public static int[] frequency(int[] a, int M) {
int[] m = new int[M];
for(int i = 0; i < a.length; i++) //loop through a
if( i < M) //number check
m[a[i]]++; //add one to m at index a[i]
return m;
}
}
this is the right code for the method frequency, also checks to see if the number is in range.
Guys i have been trying to put the last value of a matrix as the first and the first value as second but this is my out come
generated matrix es:
8, 4, 10,
4, 6, 9,
3, 9, 7,
upside down matrix:
7, 9, 3, 7, 9, 3, 7, 9, 3,
this is the code:
public String segmat(int a[][]) {
String s = "";
for (int i =0;i<a.length;i++){
//for (int i = a.length - 1; i >= 0; i--) {
for (int j = a[0].length - 1; j >= 0; j--) {
s += a[a.length - 1][j] + ", ";
}
}
return s;
}
This example can be helpful for you
I commented the code so it will be quite easy to understand
public class MatrixExample {
private static int[][] reverse(int[][] matrix){
int row=matrix.length;
int column=matrix[0].length; //we have for shure this element, his length is the number of colmn
int to_return[][] = new int[row][column]; //this is a matrix of the same dimention of the original
//the indexes that will cicle the row and the column of the new matrix
int new_row=0;
int new_column=0;
for(int i=row-1;i>-1;i--){ //this will cile the rows from the last to thee first
for(int j=column-1;j>-1;j--){ //this will cicle the colums from the last to the first
to_return[new_row][new_column]=matrix[i][j];
new_column++;
}
new_column=0;
new_row++;
}
return to_return;
}
public static void main(String[] args) {
int matrix[][] = {{ 1, 2, 3},
{4, 5, 6},
{7, 8, 9},
{10,11,12}};
int[][] new_matrix = reverse(matrix);
for(int i=0;i<new_matrix.length;i++){
for(int j=0;j<new_matrix[0].length;j++){
System.out.print(new_matrix[i][j]+" ");
}
System.out.println();
}
}
}
public class arsum
{
static int[][] myarray = {{1, 2, 3, 4}, {5, 6, 7, 8}, {1, 2, 3, 4}};
public int[] summing(int[][] array)
{
int index = 0;
int a[] = new int[array[index].length];
for (int i = 0; i < array[0].length; i++)
{
int sum = 0;
for (int j = 0; j < array.length; j++)
{
sum += array[j][i];
}
a[index] = sum;
System.out.println(sum);
}
return a;
}
public static void main(String[] args) {
new arsum().summing(myarray);
}
}
At the moment it prints out all 4 column sums, however I only want the last sum. I cannot figure out how to code it properly for any general array.
I am new to coding and have not totally figured everything out yet.
Try,
int[][] myarray = {{1, 2, 3, 4}, {5, 6, 7, 8}, {1, 2, 3, 4}};
int sum = 0;
for (int nums[] : myarray) {
sum += nums[nums.length - 1];
}
System.out.println(sum);
you can also use array indexing to print sum of last column as below:-
public static int summing(int[][] array)
{
int row = array.length;
int sum = 0;
for (int i = row - 1; i > row - 2; i--) {
int col = myarray[i].length;
for (int j = 0; j < col; j++) {
sum += array[i][j];
}
System.out.println(sum);
}
return sum;
}