I'm trying to figure out how to turn this type of input from scanner:
3
a b c
d e f
g h i
into this array:
String[][] arr = {{a,b,c}, {d,e,f}, {g,h i}}
The first row specifies the dimensions of the array, and the lines after are the matrix.
This is the code that I have so far:
Scanner scan = new Scanner(System.in);
int num = scan.nextInt();
scan.nextLine();
String[][] matrix = new String[num][num];
I know I'll probably need a loop that separates each entry in the row by spaces and then add it into the first row in the array, then check for a new line repeat with each row, but I can't figure out how to implement this code.
I've made the program in Python, but I can't figure out how to do this in Java.
The below code answers your question, namely processes the input as indicated in your question which is first obtaining the [square] matrix dimension followed by separate lines where each line contains all the elements for a single row of the matrix where the elements are separated by spaces.
import java.util.Arrays;
import java.util.Scanner;
public class Matrix {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
// Number of elements in each row and each column of matrix.
int num = scan.nextInt();
String[][] matrix = new String[num][num];
scan.nextLine(); // Ignore return value.
for (int row = 0; row < num; row++) {
// Enter elements for single row of matrix, delimited by spaces.
String line = scan.nextLine();
String[] elements = line.split("\\s+");
for (int column = 0; column < num; column++) {
matrix[row][column] = elements[column]; // Note: user entered values not checked.
}
}
System.out.println(Arrays.deepToString(matrix));
}
}
Output for a sample run of the above code, using the sample values from your question:
3
a b c
d e f
g h i
[[a, b, c], [d, e, f], [g, h, i]]
Firstly, since we are taking int rather than strings, the matrix 2d-array should be one of int.
The rest should be almost identical structurally to your python code as far as I can imagine:
...
Scanner scan = new Scanner(System.in);
int num = scan.nextInt();
int[][] matrix = new int[num][num];
scan.nextLine();
for (int i = 0; i < num; i++) {
for (int j = 0; j < num; j++) {
matrix[i][j] = scan.nextInt();
}
scan.nextLine();
}
...
You can solve this problem by looping through the rows and columns in a 2D array.
import java.util.*;
class Test {
public static void main(String[] args) {
int row = 3, column = 3;
String[][] matrix = new String[row][column];
read(matrix, row, column);
print(matrix, row, column);
}
public static void read(String[][] matrix, int row, int column) {
Scanner scanner = new Scanner(System.in);
String input;
for(int i = 0 ; i < row ; ++i) {
for(int j = 0 ; j < column ; ++j) {
input = scanner.nextLine();
matrix[i][j] = input;
}
}
}
public static void print(String[][] matrix, int row, int column) {
for(int i = 0 ; i < row; ++i) {
for(int j = 0 ; j < column ; ++j) {
String result = String.format("MATRIX [%d][%d]: %s", i, j, matrix[i][j]);
System.out.println(result);
}
}
}
}
Related
I currently have a text file in the format
matrix
row
a
b
c
row
d
e
f
row
g
h
i
row
j
k
l
matrix
row
m
n
o
p
q
row
r
s
t
u
v
I would like to convert this into two integer matrices (stored as 2 2D arrays), in the format
a b c
d e f
g h i
j k l
and
m n o p q
r s t u v
So far, I have created a Scanner object of the file and put each line in a text array:
Scanner sf = new Scanner(new File("C:\\textfiles\\matrices.txt"));
int maxIndex = -1;
String text[] = new String[10000]; // I added more than necessary for safety
while (sf.hasNext()){
maxIndex++;
text[maxIndex] = sf.nextLine();
}
sf.close();
This way, the text file is now contained in a string array, where each line is a new element of the array. Right now, I would like to partition the array into two arrays with each array being the matrices. How should I continue? (note: I am a total beginner and desire answers that are simple (no arraylist, hashmap, etc., and that's why this question is not a duplicate of How to read two matrices from a txt file in java because it uses BufferedReader, and there are other potential duplicate questions, so I would like to clear this up)
What I currently have after the top:
int counter = 0;
int iCounter = 0; // row
int jCounter = 0; // column
int matrix1[][];
int matrix2[][];
while (counter < maxIndex){
if (counter = 0)
{
\\not yet written...
}
\\not yet written...
}
As #Rob said, it's really cumbersome to do this without dynamic data structures such as ArrayList's. But nevertheless, here's a code that does your job (considering you have only two matrices), without using any List's:
int counter = 0;
int iCounter = 0; // row
int jCounter = 0; // column
int matrix1[][];
int matrix2[][];
int rowSize = 0, numberOfRows = 0;
counter = 2;
while (!text[counter].equals("row") && !text[counter].equals("matrix")) {
counter++;
rowSize++;
}
//now we have the row size
numberOfRows = 1;
while (!text[counter].equals("matrix")) {
if (text[counter].equals("row"))
numberOfRows++;
counter++;
}
//now we have the total number of rows
matrix1 = new int[numberOfRows][rowSize];
counter = 2; //to start from the first matrix
//now counter should point to the first row of the first matrix
while (!text[counter].equals("matrix")) {
jCounter = 0;
while (!text[counter].equals("row")
&& !text[counter].equals("matrix")) {
matrix1[iCounter][jCounter++] = Integer.parseInt(text[counter]);
//supposing your input is Integers, otherwise, you can change
//it to the corresponding type (i.e. Long, Double, etc)
counter++;
}
iCounter++;
if (!text[counter].equals("matrix"))
counter++;
}
//now we finished with the first matrix, and the counter points to
//the first "row" of the second matrix, so we do the same thing again
rowSize = 0;
numberOfRows = 0;
int startOfSecondMatrix = counter + 2; //save this for later
counter += 2; // so that counter points to the first number
while (counter < text.length && !text[counter].equals("row")) {
counter++;
rowSize++;
}
numberOfRows = 1;
while (counter < text.length) {
if (text[counter].equals("row"))
numberOfRows++;
counter++;
}
matrix2 = new int[numberOfRows][rowSize];
counter = startOfSecondMatrix;
iCounter = 0;
while (counter < text.length) {
jCounter = 0;
while (counter < text.length && !text[counter].equals("row")) {
matrix2[iCounter][jCounter++] = Integer.parseInt(text[counter]);
counter++;
}
iCounter++;
counter++;
}
For each matrix we perform the same operations:
-We first go through the matrix to count its size to be able to initialize it, after that, we go row by row, and parse each number.
You might as well put all the work for one matrix into a function (and take care of the bounds) and call it as long you still have more matrices.
This does what you want. Unfortunately doing this with 2D arrays is considerably harder since once you set the size of an array its difficult to manage changing it. Therefore using ArrayList is much easier.
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
class Main {
public static final String MATRIX = "matrix";
public static final String ROW = "row";
public static void main(String[] args) throws FileNotFoundException {
// Use correct file name here
Scanner sf = new Scanner(new File("matrices.txt"));
// This is a List of 2D Lists
List<List<List<String>>> matrices = new ArrayList<>();
// easier to process lines as we're reading them in so we
// only iterate over the file once
while (sf.hasNext()) {
boolean hasBeenProcessed = false;
String inputValue = sf.nextLine();
switch (inputValue) {
case MATRIX:
ArrayList<List<String>> matrix = new ArrayList<>();
matrices.add(matrix);
hasBeenProcessed = true;
break;
case ROW:
List<List<String>> currentMatrix = getMatrixBeingProcessed(matrices);
currentMatrix.add(new ArrayList<String>());
hasBeenProcessed = true;
break;
}
if (!hasBeenProcessed) {
List<List<String>> currentMatrix = getMatrixBeingProcessed(matrices);
List<String> currentRow = getCurrentRow(currentMatrix);
currentRow.add(inputValue);
}
}
// Print out the results:
int i = 1;
for (List<List<String>> matrix : matrices) {
System.out.println("Matrix " + i);
for (List<String> row : matrix) {
for (String element : row) {
System.out.print(element + " "); // no newline until end of the row
}
System.out.println(); // new line
}
i++;
System.out.println(); // new line
}
}
private static List<String> getCurrentRow(List<List<String>> currentMatrix) {
int lastRow = currentMatrix.size() - 1;
return currentMatrix.get(lastRow);
}
private static List<List<String>> getMatrixBeingProcessed(List<List<List<String>>> matrices) {
int lastMatrix = matrices.size() - 1;
List<List<String>> currentMatrix = matrices.get(lastMatrix);
return currentMatrix;
}
}
Output:
Matrix 1
a b c
d e f
g h i
j k l
Matrix 2
m n o p q
r s t u v
Process finished with exit code 0
Since you don't want to use List and arrays can't be resized once initialized, this is not easy.
There are two ways: Read the file and initialize arrays knowing the size (as #Maaddy posted) or 'resizing' arrays. That's not possible but it is if you use Arrays.copyOf() so you can create a new array.
The idea is create a 'tridimensional' array where you can store: matrix, row and column; and then start to read the file.
Every time you find a word the entire array will be updated creating a new array with one length more.
If the word is 'matrix' the extra length will be added to the first position (the position who 'store' the matrix)
If the word is 'row' then the space will be added for the current matrix. So in this way, the current matrix will have one more array where store the column values.
If the word is other then is a value for the column. The column is resized and added to the correct position.
Note that if a word 'matrix' or 'row' is found, the new array is initialized with no length. This is because will be resized later, when is necessary.
The code is as follows:
//Initialize array with no positions
String[][][] arrays = new String[0][0][0];
Scanner sf = new Scanner(new File("path/matrices.txt"));
int matrix = -1;
int row = -1;
int column = -1;
while (sf.hasNext()){
String line = sf.nextLine();
if(line.equals("matrix")) {
//'Resize' array: Create new array with 1 more length and old data
arrays = Arrays.copyOf(arrays, arrays.length + 1);
//Start new matrix
arrays[++matrix] = new String[0][0];
row = -1;
column = -1;
}else if(line.equals("row")) {
//'Resize' matrix: Create a new array with 1 more length and old data
arrays[matrix] = Arrays.copyOf(arrays[matrix], arrays[matrix].length+1);
row++;
arrays[matrix][row] = new String[0];
column = -1;
}else{
//'Resize' matrix
column++;
arrays[matrix][row] = Arrays.copyOf(arrays[matrix][row], arrays[matrix][row].length+1);
arrays[matrix][row][column] = line;
}
}
sf.close();
//Print result
for(int i = 0 ; i < arrays.length; i++) {
System.out.println("Matrix "+i);
for(int j = 0; j < arrays[i].length; j++ ) {
for(int k = 0; k < arrays[i][j].length; k++) {
System.out.print(arrays[i][j][k]+ " ");
}
System.out.println();
}
System.out.println();
}
And the result is:
Matrix 0
a b c
d e f
g h i
j k l
Matrix 1
m n o p q
r s t u v
i'm trying to solve the problem of rotation of the row of the 2 dimensional array and i given below the input output details
after input of the 1
5 2
1 2 3 4 5
i'm getting the output:-3 4 5 0 0
but the expected output is 3 4 5 1 2
package geeksforgeeks.basic;
import java.util.Scanner;
public class RotationOfAnArray
{
public static void main( String[] args )
{
Scanner sc = new Scanner( System.in );
//initializing the variables and the matrix
int i, j, n, k, l, f, p;
//taking the input
n = sc.nextInt();
int[][] arr1 = new int[100][100];
for( i = 0; i < n; i++ )
{
k = sc.nextInt();
l = sc.nextInt();
for( j = 0; j < k; j++ )
{
arr1[i][j] = sc.nextInt();
}
//in the above section taking the input of the elements of the array of the matrix
for( f = 0; f < l; f++ )
{
p = arr1[0][0];
for( j = 0; j < arr1.length - 1; j++ )
{
arr1[i][j] = arr1[i][j + 1];
}
//here the row of the particular matrix is not rotated
arr1[i][arr1.length - 1] = p;
}
for( j = 0; j < k; j++ )
{
System.out.print( arr1[0][j] + " " );
}
}
}
}
The problem with your code is you are initializing your array size as 100,and when later when you are trying to replace the last element by arr1[i][arr1.length-1]=p; it replaces last 99th index ,not 4th index. If you will iterate over complete array you can see those value sitting at last. My suggestion is initialise the array with the size of your need.
import java.util.Scanner;
public class RotationOfAnArray {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
//initializing the variables and the matrix
int i,j,n,k,l,f,p;
//taking the input
n=sc.nextInt();
int[][] arr1;
for(i=0;i<n;i++){
k=sc.nextInt();
//********Initialise array here instead.******
arr1=new int[k][k];
l=sc.nextInt();
for(j=0;j<k;j++){
arr1[i][j]=sc.nextInt();
}
//in the above section taking the input of the elements of the array of the matrix
for(f=0;f<l;f++) {
p=arr1[0][0];
for(j=0;j<arr1.length-1;j++) {
arr1[i][j]=arr1[i][j+1];
}
//here the row of the particular matrix is not rotated
arr1[i][arr1.length-1]=p;
}
for(j=0;j<k;j++) {
System.out.print(arr1[0][j]+" ");
}
}
}
}
I believe the issue was that you were overwriting the array as you were iterating through it, here is an example using a one dimensional array.
Scanner sc=new Scanner(System.in);
//initializing the variables and the matrix
int n,k,l;
//taking the input
n=sc.nextInt();//TestCases
k=sc.nextInt();//ArrayLength
l=sc.nextInt();//Rotations
int[] arr=new int[k];
for(int i=0;i<k;i++){
arr[i]=sc.nextInt();
}//in the above section taking the input of the elements of the array of the matrix
//Rotating the array
int[] backupArr = new int[k];//Backup is made as not to overwrite array
for(int i=0;i<arr.length;i++) {
backupArr[((i+arr.length-l)%arr.length)]=arr[i];//Modulo is used to keep index within constraints of array
}
arr=backupArr;//array is set to rotated instance
for(int a : arr)System.out.print(a);
While writing my code I'm getting stuck on I'm trying to return the new transposed array and actually transposing the array itself. I get the error cannot convert int to int[][]. i thought trans would be an array var. the problem code is at the way bottom. any help is greatly appreciated.
package workfiles;
import java.util.*;
import java.util.Scanner;
public class hw2 {
// Do not modify this method
public static void main(String[] args) {
try
{
int [][] iArray = enter2DPosArray();
System.out.println("The original array values:");
print2DIArray(iArray);
int [][] tArray = transposition(iArray);
System.out.println("The transposed array values:");
print2DIArray(tArray);
}
catch (InputMismatchException exception)
{
System.out.println("The array entry failed. The program will now halt.");
}
}
// A function that prints a 2D integer array to standard output
// It prints each row on one line with newlines between rows
public static void print2DIArray(int[][] output) {
for (int row = 0; row < output.length; row++) {
for (int column = 0; column < output[row].length; column++) {
System.out.print(output[row][column] + " ");
}
System.out.println();
}
}
// A function that enters a 2D integer array from the user
// It raises an InputMismatchException if the user enters anything other
// than positive (> 0) values for the number of rows, the number of
// columns, or any array entry
public static int[][] enter2DPosArray() throws InputMismatchException {
int row=0;
int col=0;
int arow=0;
int acol=0;
int holder;
Scanner numScan = new Scanner(System.in);
while (row<=0){
System.out.print("How many rows (>0) should the array have? ");
row = numScan.nextInt();
}
while (col<=0){
System.out.print("How many columns (>0) should the array have? ");
col = numScan.nextInt();
}
int[][] iArray = new int[row][col];
while (arow < row) {
while (acol < col) {
System.out.println("Enter a positive (> 0) integer value: ");
holder = numScan.nextInt();
iArray[arow][acol] = holder;
acol++;
}
if (acol >= col) {
acol = 0;
arow ++;
}
}
//arrayName[i][j]
numScan.close();
return iArray;
}
//!!! problem code here!!!
public static int[][] transposition(int [][] iArray) {
int m = iArray.length;
int n = iArray[0].length;
int trans[][];
for(int y = 0; y<m; y++){
for(int x = 0; x<n; x++){
trans = iArray[y][x] ;
}
}
return trans;
}
}
You missed two things
1.) initialization of trans
int trans[][]= new int [n][m];
2.) trans is a 2D array
trans[y][x] = iArray[y][x] ;
//trans = iArray[y][x] ; error
Update : To form this logic , we need index mapping like this
// trans iArray
// assign values column-wise row-wise
// trans[0][0] <= iArray[0][0]
// trans[1][0] <= iArray[0][1]
// trans[2][0] <= iArray[0][2]
mean traverse the iArrays row-wise and assign values to trans array columns-wise
int m = iArray.length;
int n = iArray[0].length;
// iArray[2][3]
int trans[][] = new int[n][m];
// 3 2
for(int y = 0; y<m; y++){
for(int x = 0; x<n; x++){
trans[x][y] = iArray[y][x] ;
}
}
I have an assignment to design and implement methods to process 2D Arrays.
It needs to have an implementation class (Array2DMethods) that has the following static methods:
readInputs() to read the number of rows and columns fro the user then reads a corresponding entry to that size. Ex: if a user enters 3 for # of rows and 3 for # of columns it'll declare an array of 10 and reads 9 entries.
max(int [][] anArray) it returns the max value in the 2D parameter array anArray
rowSum(int[][] anArray) it returns the sum of the elements in row x of anArray
columnSum(int[][] anArray) it returns the sum of the elements in column x of anArray **careful w/ rows of different lengths
isSquare(int[][] anArray) checks if the array is square (meaning every row has the same length as anArray itself)
displayOutputs(int[][] anArray) displays the 2 Dim Array elements
It also needs a testing class (Arrays2DDemo) that tests the methods.
I've commented the parts I'm having problems with. I'm not sure how to test the methods besides the readInputs method and also not sure how to format the part where you ask the user to enter a number for each row.
Here's my code so far:
import java.util.Scanner;
class Array2DMethods {
public static int [][] readInputs(){
Scanner keyboard = new Scanner(System.in);
System.out.print(" How many rows? ");
int rows = keyboard.nextInt();
System.out.print(" How many columns? ");
int columns = keyboard.nextInt();
int [][] ret = new int[rows][columns];
for (int i = 0; i<ret.length; i++) {
for (int j = 0; j < ret[i].length; j++) {
System.out.print("please enter an integer: "); //Need to format like Enter [0][0]: ... Enter [0][1]: ...etc.
ret[i][j] = keyboard.nextInt();
}
}
return ret;
}
public static int max(int [][] anArray) {
int ret = Integer.MIN_VALUE;
for (int i = 0; i < anArray.length; i++) {
for (int j = 0; j < anArray[i].length; j++) {
if (anArray[i][j] > ret) {
ret = anArray[i][j];
}
}
}
return ret;
}
public static void rowSum(int[][]anArray) {
int ret = 0;
for (int i = 0; i<anArray.length; i++) {
for (int j = 0; j < anArray[i].length; j++) {
ret = ret + anArray[i][j];
}
}
}
public static void columnSum(int[][]anArray) {
int ret = 0;
for (int i = 0; i < anArray.length; i++) {
for (int j = 0; j < anArray[i].length; j++) {
ret = ret + anArray[i][j];
}
}
}
public static boolean isSquare(int[][]anArray) {
for (int i = 0, l = anArray.length; i < l; i++) {
if (anArray[i].length != l) {
return false;
}
}
return true;
}
public static void displayOutputs(int[][]anArray) {
System.out.println("Here is your 2Dim Array:");
for(int i=0; i<anArray.length; i++) {
for(int j=0; j<anArray[i].length; j++) {
System.out.print(anArray[i][j]);
System.out.print(", ");
}
System.out.println();
}
}
}
Class Arrays2DDemo:
public class Arrays2DDemo {
public static void main(String[] args){
System.out.println("Let's create a 2Dim Array!");
int [][] anArray = Array2DMethods.readInputs();
Array2DMethods.max(anArray);
Array2DMethods.rowSum(anArray);
//need to print out and format like this: Ex Sum of row 1 = 60 ...etc
Array2DMethods.columnSum(anArray);
//need to print out and format like this: Ex Sum of column 1 = 60 ...etc.
Array2DMethods.isSquare(anArray);
//need to print out is this a square array? true
Array2DMethods.displayOutputs(anArray);
//need it to be formatted like [10, 20, 30] etc
}
}
Assuming you want anArray to be the array you read in during your inputting, you should name that variable, as such...
public static void main(String[] args){
System.out.println("Let's create a 2Dim Array!");
int[][] anArray = Array2DMethods.readInputs();
System.out.println("max " + Array2DMethods.max(anArray));
Array2DMethods.rowSum(anArray);
Array2DMethods.columnSum(anArray);
System.out.println("Square " + Array2DMethods.isSquare(anArray));
Array2DMethods.displayOutputs(anArray);
}
Say you have a function f which takes a single input x. The problem is you're asking the computer to evaluate f(x) without ever telling it what x is. If you give x a value, however, such as x = 3, then asking f(x) becomes legal, because it becomes f(3), which can be evaluated.
How do I change a set array sized into a random sized array chosen by the user.
Here is how I have it setup for set a sized array. I just do not know how to convert over to a random sized....
import java.util.Scanner;
public class Project1a {
public static void scanInfo()
{
Scanner input = new Scanner(System.in);
System.out.println("Enter number of rows: ");
int rows = input.nextInt();
System.out.println("Enter number of columns: ");
int columns = input.nextInt();
int[][] nums = new int[rows][columns];
static int[][] sample = nums;
}
static int[][] results = new int[4][5];
static int goodData = 1;
public static void main(String[] args) {
analyzeTable();
printTable(results);
}
static void analyzeTable() {
int row=0;
while (row < sample.length) {
analyzeRow(row);
row++;
}
}
static void analyzeRow(int row) {
int xCol = 0;
int rCount = 0;
while (xCol < sample[row].length) {
rCount = analyzeCell(row,xCol);
results[row][xCol] = rCount; // instead of print
xCol++;
}
}
static int analyzeCell(int row, int col) {
int xCol = col; // varies in the loop
int runCount = 0; // initialize counter
int rowLen = sample[row].length; // shorthand
int hereData = sample[row][xCol]; // shorthand
while (hereData == goodData && xCol < rowLen) {
runCount++;
xCol++;
if (xCol < rowLen) { hereData = sample[row][xCol];}
}
return runCount;
}
/* Start Print Stuff */
public static void printTable(int[][] aTable ) {
for (int[] row : aTable) {
printRow(row);
System.out.println();
}
}
public static void printRow(int[] aRow) {
for (int cell : aRow) {
System.out.printf("%d ", cell);
}
}
}
/* End Print Stuff */
I am now only getting one error at line 18: illegal start of expression. I do not think I have the variables defined correctly.
You could re-write your code in order to use ArrayList's:
import java.util.ArrayList;
//Here you create an 'array' that will contain 'arrays' of int values
ArrayList<ArrayList<Integer>> sample = new ArrayList<ArrayList<Integer>>();
then add each row:
sample.add(new ArrayList<Integer>());
and add an element to a row:
sample.get(0).add(5); // get(0) because is the first row, and 5 is int
Of course you will have to modify your code to use this kind of array.
You can't change array sizes in Java, although it gets complicated when working with multi-dimensional arrays. I would recommend familiarizing yourself with the Java Array docs.
What you can do is create a new array of the desired size and then copying data from the old array into the new one.
Scanner input = new Scanner(System.in);
System.out.println("Enter number of rows: "); // get number of rows
int rows = input.nextInt();
System.out.println("Enter number of columns: "); // get number of columns
int columns = input.nextInt();;
int[][] nums = new int[rows][columns]; // new 2D array, randomly
// sized by user input
Is this all you're looking for? Based off your question, that's what it seems like
If you want a method populate it with random 1's and 0's, Just do this
static void populate(int[][] nums) {
for (int i = 0; i < row.length; i++) {
for (int j = 0; j < column.length; i++) {
nums[row][column] = (int)(Math.random() + 1);
}
}
}
Now num is a 2D matrix with random 1's and 0's