Doubling a Matrix - java

I've created a two dimensional matrix and populated it with random numbers. I've then printed it out. I need help creating a second matrix that is twice the size of the first, and is populated with the numbers from the first one (which are now 2x2). For example:
Starting Matrix:
3 4
2 1
Doubled Matrix:
3 3 4 4
3 3 4 4
2 2 1 1
2 2 1 1

import java.util.Scanner;
import java.util.Random;
public class MatrixDoubler {
public static void main(String[] arg) {
Scanner keyboard = new Scanner(System.in);
Random rand = new Random();
System.out.println("Enter the size of the matrix");
int size = keyboard.nextInt();
int A[][] = new int[size][size];
for (int row = 0; row < size; ++row) {
for (int col = 0; col < size; ++col) {
A[row][col] = rand.nextInt(10);
}
}
System.out.println("Matrix A:");
printMatrix(A);
int[][] B = doubleMatrix(A);
System.out.println("Matrix B:");
printMatrix(B);
}
private static int[][] doubleMatrix(int[][] A) {
int rows = A.length;
assert(rows > 0);
int cols = A[0].length;
assert(cols > 0);
int B[][] = new int[rows * 2][cols * 2];
for (int row = 0; row < rows * 2; ++row) {
for (int col = 0; col < cols * 2; ++col) {
B[row][col] = A[row / 2][col / 2];
}
}
return B;
}
private static void printMatrix(int[][] M) {
for(int i = 0; i < M.length; i++) {
for(int j = 0; j < M.length; j++) {
System.out.print(M[i][j] + " ");
}
System.out.println();
}
}
}

I'm no sure if that is what you are looking for but try this:
for (int i = 0; i < newMatrix.length; i++) {
for (int j = 0; j < newMatrix.length; j++) {
newMatrix[i][j] = matrix[i/size][j/size];
}
}
Note: This code is surely not the best solution but a fast an easy one. It only works if both dimensions are the same size and it won't work if newMatrix is not exactly two times matrix. If it's always just to "double" a matrix it should work fine.
Output:
If you choose size 2 than it will output:
Enter the size of the matrix
2
The Matrix is
3 5
5 2
The newMatrix is
3 3 5 5
3 3 5 5
5 5 2 2
5 5 2 2
and for size 3 it would be for example
Enter the size of the matrix
3
The Matrix is
4 4 3
5 9 4
7 4 1
The newMatrix is
4 4 4 4 3 3
4 4 4 4 3 3
5 5 9 9 4 4
5 5 9 9 4 4
7 7 4 4 1 1
7 7 4 4 1 1
It's not clear what you are asking but I hope this helps (:

In Java 8 you can handle this pretty easily using maps and collectors. Here is a full example:
public class DoubleMatrix {
public static void main(String[] args) {
List<List<Integer>> startingMatrix = Arrays.asList(
Arrays.asList(3, 4),
Arrays.asList(2, 1)
);
List<List<Integer>> doubleMatrix
= startingMatrix.stream()
.map(innerList -> { //For each list
List<Integer> doubled = innerList.stream()
.map(element -> Arrays.asList(element, element)) //Return a list doubling each element
.flatMap(l -> l.stream()) //Flatten out/join all doubled lists
.collect(Collectors.toList());
return Arrays.asList(doubled, doubled); //Double the list
})
.flatMap(l -> l.stream())
.collect(Collectors.toList()); //Collect into a final list
System.out.println(doubleMatrix);
}
}
This avoids needing to know the size of the list beforehand, and is also tolerant of there being a difference between the width and height of your matrix - simply doubling every element in both directions.

Related

how to print two dimensional array correctly?

my output is
4 4 8 7
3 3 3 5 6 3 3 4 5
when it should be
4 4 5
8 7 7
3 3 3 4
5 6 3 1
3 4 5 6
i need to use same method for all of arrays, summing up arrays of two matrices.
how can i do that when arrays are different length and how can i print output correctly?
public static void main(String[] args) {
int[][] m1 = { { 1, 2, 0 }, { 2, 3, 4 } };
int[][] m2 = { { 3, 2, 5 }, { 6, 4, 3 } };
int[][] m3 = { { 1, 1, 1, 1 }, { 3, 3, 2, 1 }, { 2, 2, 2, 2 } };
int[][] m4 = { { 2, 2, 2, 3 }, { 2, 3, 1, 0 }, { 1, 2, 3, 4 } };
printMatrixSum(m1, m2);
System.out.println();
printMatrixSum(m3, m4);
}
private static void printMatrixSum(int[][] x, int[][] y) {
int c[][] = new int[4][4];
for (int i=0; i < 2; ++i) {
for(int j=0;j<3;j++) {
c[i][j]=x[i][j]+y[i][j];
System.out.print(c[i][j]+" ");
}
}System.out.println();
}
}
Your code is close to working. I made some changes below, and it now produces this output:
4 4 5
8 7 7
3 3 3 4
5 6 3 1
3 4 5 6
Here's the code:
1. private static void printMatrixSum(int[][] x, int[][] y) {
2. int[][] c = new int[x.length][x[0].length];
3. for (int i = 0; i < x.length; i++) {
4. for (int j = 0; j < x[0].length; j++) {
5. c[i][j] = x[i][j] + y[i][j];
6. System.out.print(c[i][j] + " ");
7. }
8. System.out.println();
9. }
10. }
Here are the edits I made:
line 2: change int c[][] to int[][] c – this is minor, but follows Java style
line 2: change new int[4][4] to use actual values for array length. The first dimension is just x.length, and the second is x[0].length. This will work correctly with different array inputs vs. hard-coding to "4".
line 3: change i < 2 condition to use the length of one of the input arrays; I chose x but it could be y (and of course this code assumes that x and y are matching dimensions)
line 3: change ++i to i++ – not sure why you were using pre-increment, but in my opinion that makes it harder to reason about loop behavior, and also the second loop (line 4) was already doing post-increment (j++) so I edited this one to make it both clearer as well as consistent with the rest of your code.
line 4: change j < 3 to be dynamic, similar to edit on line 3
line 8: move the println() here, so that a newline is printed after each row of the array is printed
Instead of printing it with fixed sizes ( like i < 2 and j <3 ), use the dimension of the array to make your function more reusable.
ii) Secondly, the println() should be outside the inner loop but inside the outer loop .
private static void printMatrixSum(int[][] x, int[][] y) {
int c[][] = new int[4][4];
for (int i = 0; i < x.length; ++i) {
for (int j = 0; j < y[0].length; j++) {
c[i][j] = x[i][j] + y[i][j];
System.out.print(c[i][j] + " ");
}
System.out.println();
}
}
and this is the answer :
4 4 5
8 7 7
3 3 3 4
5 6 3 1
3 4 5 6
A couple suggestions.
Consider not writing a printMatrixSum method. Write a method to print a matrix. You may not always want to print a matrix after you compute the sum. Of course that means iterating over the matrix twice so it's ultimately going to be based on your requirements.
specify a width value to help nicely format the output.
And you don't need to index the matrix. Multi-dimensional arrays are simply arrays of other arrays. So you can use the enhanced forloop to first iterate the rows, and then the values in each row.
Here is an example.
int [][] data = {{203,2,3334,-22022, 23},{2,1,233, 42,33}};
matPrint(data, 7);
prints
203 2 3334 -22022 23
2 1 233 42 33
use the width to specify the largest value(including sign)
create a format for System.out.printf
then simply iterate the rows. and within each row, iterate the values.
public static void matPrint(int[][] m, int width) {
String fmt = "%" + width + "s";
for (int[] row : m) {
for (int col : row) {
System.out.printf(fmt, col);
}
System.out.println();
}
}
If you have a specific width that you want to use often you can overload the print method as follows. Then you can use the one argument version which invokes the two argument with the default width.
private static int DEFAULT_WIDTH = 4;
public static void matPrint(int[][] m) {
matPrint(m, DEFAULT_WIDTH);
}
And if you specify the field width as a negative value, it will left justify the output within each field.

Need help shifting latin square in Java

I'm currently making a latin square that starts with a user-set number but for simplicity's sake I'll exclude Scanner code.
public static void main(String[] args){
int first = 2; // starting integer on square
int order = 4; //max integer
String space = new String(" ");
for (int row = 0; row < order; row++)
{
for (int column = 0; column < order; column++)
{
for (int shift = 0; shift < order; shift++)
{
int square = ((column+(first-1)) % order + 1); //this makes a basic square with no shifting
int latin = square+shift; //this is where my code becomes a mess
System.out.print(latin + space);
}
System.out.println();
}
}
}
}
Which prints out:
2 3 4 5
3 4 5 6
4 5 6 7
1 2 3 4
2 3 4 5
3 4 5 6
4 5 6 7
1 2 3 4
It's so close, considering the fact that it does start with my pre-determined first digit and it's printing only 4 integers.
The problem I'm running into is the fact that it's going further than my order integer and that it's printing double the rows.
Any idea what I can do to fix this?
For reference, this is what I want it to print:
2 3 4 1
3 4 1 2
4 1 2 3
1 2 3 4
It seems that the innermost loop for (int shift...) is redundant and it causes duplication of the output, the latin value should be calculated using row parameter:
public static void main(String args[]) {
int first = 2; // starting integer on square
int order = 4; //max integer
String space = " ";
for (int row = 0; row < order; row++) {
for (int column = 0; column < order; column++) {
int latin = (row + column + first - 1) % order + 1;
System.out.print(latin + space);
}
System.out.println();
}
}
Output:
2 3 4 1
3 4 1 2
4 1 2 3
1 2 3 4

Fill an integer array with a series of number that is a string (java)

Im trying to write the following program, where i have a string that a number is generated possibly like 37 digits.
Is it possible to fill an array that i know the length but not the rows because the string can be anything.
String number; //110034043312132121220023020423340432 but can be any big number that is converted to a string
System.out.println("Give length in a form of a string: ");
String input= scan.nextLine(); //abcdefg
int length = input.length(); //this means i get 6 back.
And save this in a character array where i know the length from input.lenght() and i dont know the rows
A B C D E F G
1 1 0 0 3 4 0
4 3 3 1 2 1 3
2 1 2 1 2 2 0
0 2 3 0 2 0 4
2 3 3 4 0 4 3
2
I know the answer might be something stupid simple but please be coder noob friendly. Thanks
The solution may be as follows:
Use input.length as the max number of columns in the resulting 2D array
Calculate the number of rows in the resulting 2D array nums / cols, adding one extra row if there's a remainder.
The last row in the result may be jagged: contain less than cols elements.
String number = "110034043312132121220023020423340432"; // but can be any big number that is converted to a string
System.out.println("Give length in a form of a string: ");
String input= "ABCDEFG" ; //scan.nextLine(); //abcdefg
int cols = input.length(); // columns in the resulting array
int nums = number.length(); // total count of numbers
int rows = nums / cols + (nums % cols == 0 ? 0 : 1);
int[][] result = new int[rows][]; // the result may be jagged
for (int i = 0; i < rows - 1; i++) {
result[i] = new int[cols];
}
result[rows - 1] = new int[nums % cols == 0 ? cols : nums % cols];
for (int i = 0; i < nums; i++) {
int r = i / cols;
int c = i % cols;
result[r][c] = number.charAt(i) - '0';
}
// print the result
System.out.println(input.replaceAll(".", "$0 ")); // print header with spaces between columns
for (int[] row : result) {
System.out.println(Arrays.toString(row)
.replaceAll("[^\\s\\d]", "") // remove brackets and comma from output
);
}
Output:
A B C D E F G
1 1 0 0 3 4 0
4 3 3 1 2 1 3
2 1 2 1 2 2 0
0 2 3 0 2 0 4
2 3 3 4 0 4 3
2
To do this, you might be able to use a list instead.
ArrayList<int[]> list = new ArrayList<int[]>();
and in each line, you can add a new array into the list.
If you want the final result to be a 2d array, you can easily convert a list to an array.
public static char[][] createMatrix(String num, String title) {
int totalRows = (int)Math.ceil((double)num.length() / title.length());
char[][] matrix = new char[totalRows + 1][title.length()];
for (int i = 0; i < matrix[0].length; i++)
matrix[0][i] = title.charAt(i);
for (int i = 0, row = 1, col = 0; i < num.length(); i++) {
matrix[row][col++] = num.charAt(i);
if (col == matrix[row].length) {
row++;
col = 0;
}
}
return matrix;
}

Can this O(n) Matrix Rotation algorithm be done in place and remain O(n)?

Question:
Can the algorithm posted below be adjusted to use the same array (which represents a 2D matrix) for a clockwise rotation instead of using a second array and still remain at O(n) complexity?
Code:
import java.util.Random;
public class MatrixRotation {
public static void main(String[] args) {
int dimension = 5;
int[] array = generate(dimension);
print(array, dimension);
int[] clockwise = clockwise(array, dimension);
print(clockwise, dimension);
}
//Generate a matrix with random values
private static int[] generate(int dimension) {
Random rand = new Random();
int[] array = new int[dimension * dimension];
for(int i = 0; i < array.length; i++) {
array[i] = rand.nextInt(10);
}
return array;
}
//Rotates the matrix clockwise by calculating where the value's position should be after the rotation
private static int[] clockwise(int[] array, int dimension) {
int[] rotated = new int[array.length];
int baseCount = dimension;
for(int i = 0; i < array.length; i++) {
int remainder = i % dimension;
if(remainder == 0)
baseCount--;
int position = baseCount + (dimension * remainder);
//I suspect I can do some kinda swapping functionality here but am stumped
rotated[position] = array[i];
}
return rotated;
}
//Used to display the matrix
private static void print(int[] array, int dimension) {
for(int i = 0; i < array.length; i++) {
if(i % dimension == 0)
System.out.println();
System.out.print(array[i] + " ");
}
System.out.println();
}
}
Sample Output:
1 7 4 1 4
2 3 5 2 9
4 3 9 3 1
5 8 7 5 6
3 3 7 2 5
3 5 4 2 1
3 8 3 3 7
7 7 9 5 4
2 5 3 2 1
5 6 1 9 4
Background:
I was reading a question the other day about matrix rotations represented in a 1D array and decided to take swing at it. I managed to successfully create a rotation algorithm by calculating the next position of the value after the rotation. Currently I'm trying to determine if there's a way to keep it as O(n) while reducing the space used by keeping it inside the same array. Any thoughts on how to achieve this?
I found a working solution! I wasn't able to determine how to make it work with the posted algorithm, but once I started designing it from scratch with rotation swapping from the start I found a solution in the same complexity (essentially). I designed it with the idea of working from the outside to the inside via "onion layers" by finding the corners of each layer and then rotating them and their relative directional adjacent. Something like:
↓ ↓ ↓
5 5 8 2 1 ← 7 5 8 2 5 7 2 8 2 5
9 4 8 2 3 9 4 8 2 3 ← 9 4 8 2 5
6 3 7 5 4 6 3 7 5 4 → 6 3 7 5 4 ← Ect...
2 6 4 2 7 → 2 6 4 2 7 5 6 4 2 7
→ 7 0 7 5 5 5 0 7 5 1 5 0 7 3 1
↑ ↑ ↑
For each layer.
Code:
private static int[] clockwise2(int[] array, int dimension) {
int layers = dimension / 2; //Total layers of the onion
//Loop through the layers
for (int i = 0; i < layers; i++) {
int layerWidth = dimension - 2 * i; //Current layer width
int topStart = i + dimension * i; //Top left corner
int rightStart = topStart + (layerWidth - 1); //Top right corner
int bottomStart = (array.length - 1) - topStart; //Bottom right corner
int leftStart = bottomStart - (layerWidth - 1); //Bottom left corner
//Loop values in current layer
for (int j = 0; j < layerWidth - 1; j++) {
int topIndex = topStart + j; //Move right
int rightIndex = rightStart + dimension * j; //Move down
int bottomIndex = bottomStart - j; //Move left
int leftIndex = leftStart - dimension * j; //Move up
//Swap the values in a circular direction
int temp = array[topIndex];
array[topIndex] = array[leftIndex];
array[leftIndex] = array[bottomIndex];
array[bottomIndex] = array[rightIndex];
array[rightIndex] = temp;
}
}
return array;
}

Permutation using ArrayList<Integer> to print by size of 10 in a console

I wrote simple code on random permutation between 1 to 10 using ArrayList. How can I make ArrayList in my file SmartPermutationGenerator to print the result by size of 10 in a console to get output as below:
I don't want this output:
Random arrays using Smart Force:
8 4 8 1 8 4 10 8 4 1 7 8 4 1 10 5 8 4 1 10 7 2 8 4 1 10 7 5 9 8 4 1 10 7 5 2 6 8 4 1 10 7 5 2 9 3 8 4 1 10 7 5 2 9 6
I want this output instead:
Random arrays using Smart Force:
8 4 8 1 8 4 10 8 4 1
7 8 4 1 10 5 8 4 1 10
7 2 8 4 1 10 7 5 9 8
4 1 10 7 5 2 6 8 4 1
10 7 5 2 9 3 8 4 1 10
7 5 2 9 6
Should limit the solution using arraylist only, don't want to use recursion.
This is my file SmartPermutationGenerator
import java.util.ArrayList;
import java.util.Random;
public class SmartPermutationGenerator
{
private int size;
private Random rand = new Random();
public SmartPermutationGenerator()
{
this.size = 10;
}
public ArrayList nextPermutation()
{
ArrayList<Integer> unused = new ArrayList<Integer>();
for (int i = 0; i < size; i++) // loop for element in array
{
unused.add(i + 1);
}
ArrayList<Integer> perm = new ArrayList<Integer>();
for (int k = 0; k < size; k++) //loop for random number between 1 to 10
{
int pos = rand.nextInt(unused.size());
perm.add(unused.get(pos));
unused.remove(pos);
System.out.print(perm.get(k) + " ");
for (int j = 0; j < k; j++)
{
System.out.print(perm.get(j) + " "); //loop for permutation 10 times
//System.out.println();
}
}
return perm;
}
}
This is my file BrutePermutationGenerator
import java.util.Random;
public class BrutePermutationGenerator
{
private int[] num = new int[10];
public int[] nextPermutation()
{
Random rand = new Random();
for (int j = 0; j < 10; j++)//loop for permutation 10 times
{
for (int i = 0; i < 10; i++)//loop for random number between 1 to 10
{
int low = 1;
int high = 10;
int range = high - low + 1;
int r = rand.nextInt(range);
num[i] = num[r];
num[r] = i;
}
for (int i = 0; i < 10; i++)// loop for element in array
{
System.out.print(num[i] + 1 + " ");
}
System.out.println();
}
return num;
}
}
This is my main file PermutationGeneratorViewer
public class PermutationGeneratorViewer
{
public static void main(String[] args)
{
BrutePermutationGenerator brute = new BrutePermutationGenerator();
SmartPermutationGenerator smart = new SmartPermutationGenerator();
System.out.println("\n" + "Random arrays using Brute Force: ");
brute.nextPermutation();
System.out.println("\n" + "Random arrays using Smart Force: ");
smart.nextPermutation();
}
}
You can use the modulus operator (%) in the printing loops to see if the index is a multiple of ten. If it is, print a newline.
Something like this would work:
for(...){
System.out.print(...);
if(count%10==0 && count!=0){ // if the index of the number is a multiple of 10 but not the first number
System.out.println(); // print a newline to separate rows
}
}
This will add a newline after the 10th, 20th, 30th, etc. numbers.
Another excellent solution is to create function for permutation to be repeated in file SmartPermutationGenerator as below:
public ArrayList<Integer> getRandomPermutation()
{
ArrayList<Integer> unused = new ArrayList<>();
.
.
.
}
public void nextPermutation()
{
for(int i = 0; i < size; i++) //loop for permutation 10 times
{
for(Integer item : getRandomPermutation())
{
System.out.print(item + " ");
}
System.out.println();
}
}
Solution credited to Mr.Soleh Abd Wahab.

Categories