Adding columns in an array that is created using command line arguments - java

My goal for this program is to create a 2D-array ratings whose size is specified by the first two arguments from the command line. args[0] would represent the number of rows r and arg[1] would represent the number of columns c. The next arguments that follow would all be used to fill in the array. So if the command-line argument was 3 2 5 2 3 3 4 1. I would hope that the array would be 3 rows by 2 columns. The value 5 would be in ratings[0][0], the value 2 would be in ratings[0][1], the value 3 would be in ratings[1][0], etc. After that, I want to compute the sum of each column. So column 0 would be 12 and column 1 would be 6 in this scenario.
public static void main(String[] args) {
int r = Integer.parseInt(args[0]);
int c = Integer.parseInt(args[1]);
int[][] ratings = new int[r][c];
int z = 2;
int y = 3;
int x = 0;
int counting = 0;
int sum = 0;
for (int rows = 0; rows < ratings.length; rows++ ) {
for (int column = 0; column < ratings[c].length; column++){
ratings[rows][column] = Integer.parseInt(args[z]);
sum += ratings[rows][column];
z++;
}
System.out.println(sum);
sum = 0;
}
//System.out.println(movieRating);
}
This is my attempt at summing the columns but this right now just sums 5 and 2, 3 and 3, 4 and 1. I want the columns not the rows to be summed but do not know how to fix it. Thank you

You seem to be adding the values to the 2D array correctly. What you're missing is an additional nested loop to print out the column totals:
for (int i = 0; i < ratings[c].length; i++) {
int colSum = 0;
for (int j = 0; j < ratings.length; j++) {
colSum += ratings[j][i];
}
System.out.println(colSum);
}
Add that where you currently have that //System.out.println(movieRating); line. Since you were adding the numbers to the array row-wise, you need to flip the for loops to be able to sum the columns.

Things you did right
You correctly initialized the ratings 2D-array with the values given on the command line. Let me re-write this below without your attempt at computing the columns' sum. Note that I renamed the variables so that the indices used in the for loop are single letter variable.
public static void main(String[] args) {
int rows = Integer.parseInt(args[0]);
int columns = Integer.parseInt(args[1]);
int[][] ratings = new int[rows][columns];
int argIndex = 2;
for (int r = 0; r < ratings.length; r++ ) {
for (int c = 0; column < ratings[r].length; c++){
ratings[r][c] = Integer.parseInt(args[argIndex]);
argIndex++;
}
}
}
Thing you didn't get right
The ratings array is filled row by row. In the code you posted, you compute in variable sum the sum of the elements inserted in the same row. This is the reason why it doesn't print the results you expected.
To compute the sum of each columns, I would recommend you create a new array in which to store this result. Integrating it with the code above:
public static void main(String[] args) {
int rows = Integer.parseInt(args[0]);
int columns = Integer.parseInt(args[1]);
int[][] ratings = new int[rows][columns];
int[] columnSums = new int[columns];
int argIndex = 2;
for (int r = 0; r < ratings.length; r++ ) {
for (int c = 0; column < ratings[r].length; c++){
ratings[r][c] = Integer.parseInt(args[argIndex]);
columnSums[c] += ratings[r][c];
argIndex++;
}
}
// array columnSums contains your results
}

I have changed your original code with a simpler version.
Let me know if you have problems understanding the solution.
public static void main(String[] args)
{
int row = Integer.parseInt(args[0]);
int col = Integer.parseInt(args[1]);
int arrayLength = row * col; // use a single dimension array, for simplicity
int[] ratings = new int[arrayLength]; // the array size is based on the rows and columns
// add data to the 'ratings' array
// This is not actually needed because the conversion can be done directly when the columns are summed up
for(int i = 0; i < arrayLength; i++)
{
ratings[i] = Integer.parseInt(args[i + 2]);
}
// sum up the columns using the % operator
int[] result = new int[col];
for(int i = 0; i < arrayLength; i++)
{
result[i % col] += ratings[i];
}
// print result
for(int i = 0; i < result.length; i++)
{
System.out.println(String.format("Movie %d rating is %d", i, result[i]));
}
}
PS: you are missing the validation around the String to int conversion and checks around the correctness of the user input

Related

How to find largest 10 elements in multi dimentional array?

I hope this will print one largest value. but it need 10 largest elements in an 3D array.
public class foo{
Public static void main(String[] args){
int row,col,dep=3;
int[][][] value=new int[row][col][dep];
/* insert the value from user or initialize the matrix*/
int max=0;
for(row=0;row<3;row++)
for(col=0;col<3;col++)
for(dep=0;dep<3;dep++)
if(value[row][col][dep]>max)
max=value[row][col][dep];
System.out.println(max);
}
}
You can add all integers into a List<Integer>, sort it, and then get the X max numbers of it:
public class foo {
public static void main(String[] args) {
int row = 3, col = 3, dep = 3;
int[][][] value = new int[row][col][dep];
value[1][2][1] = 10;
value[1][0][1] = 15;
List<Integer> listWithAll = new ArrayList<>();
/* insert the value from user or initialize the matrix*/
int max = 0;
for (row = 0; row < 3; row++)
for (col = 0; col < 3; col++)
for (dep = 0; dep < 3; dep++)
listWithAll.add(value[row][col][dep]);
listWithAll.sort(Collections.reverseOrder());
for (int i = 0; i < 10; i++) {
System.out.println(listWithAll.get(i));
}
}
}
which prints:
15 10 0 0 0 0 0 0 0 0
or using Java 8 streams only:
List<Integer> max10 = listWithAll.stream()
.sorted(Collections.reverseOrder())
.limit(10)
.collect(Collectors.toList());
max10.forEach(System.out::println);
Here is a way to do it with streams. I used a complete 2 x 2 x 2 array to make it easier but it would work with any int[][][] array. Instead of using nested loops, I just flatMapped the arrays.
Initialize the array.
int[][][] v = {{{1, 2}, {3, 4}}, {{5, 6}, {7, 8}}};
Now get the top4 values (or top N values) and put them in a list.
int top4 = 4;
List<Integer> top4Max =
Arrays.stream(v).flatMap(Arrays::stream).flatMapToInt(
Arrays::stream).boxed().sorted(
Comparator.reverseOrder()).limit(top4).collect(
Collectors.toList());
System.out.println(top4Max);
Prints
8 7 6 5
The Arrays.stream strips one level of array. The flatMap takes those and further flattens them into a single dimenion array. The flatMapToInt flattens that into a stream of ints where they are sorted and processed into a limited collection.
If required, you could also put them in an array instead of a list.
Alternatively, one could create a small array and use it as with a normal findmax function.
public class Array_3D {
public static void main(String[] args) {
int row = 3, col = 3, dep = 3;
int[][][] value = new int[row][col][dep];
value[1][2][1] = 10;
value[1][0][1] = 15;
int[] topten = new int[10]; //array to hold max values
int count = 0;
int candidate = 0;
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
for (int k = 0; k < dep; k++) {
if (count < 10) { //start with first ten values
topten[count] = value[i][j][k];
count++;
}
else {
candidate = value[i][j][k];
for (int x = 0; x < 10; x++) { //loop for loading top values
if (candidate > topten[x]) {
topten[x] = candidate;
break; //exit on first hit
}
}
}
}
}
}
for (int i = 0; i < 10; i++) {
System.out.print(topten[i] + " ");
}
System.out.println();
}
}
I don't know which method is faster for large 3D arrays; here we have to run a small loop at every point in the 3D array, vs creating an entirely new list and sorting it. Clearly this wins in memory usage, but not sure about speed. [Edit note this returns an unsorted array of the top ten values as is].

Java 2D arrays coin collection game from larger neigbouring cell

My issue is the following:
I have a 2D array of size n x m, entered on a single line. On the next n lines there are m number of elements, that fill the array. So far so good.
There is a pawn on the field that always starts at the only 0 on the field (assuming there is always one 0).
It can move up and down, right and left. It always moves to the neighbouring cell with most coins and at each move collects 1 coin (=> empties the visited cell by 1). The pawn does this until there are only 0s around it and it can collect nothing anymore. I need to find the sum of all coins collected.
Here is a representation of first steps in Paint:
Coin Collection first steps:
Sample input:
4 3, 3 2 4, 2 0 3, 1 1 5, 2 2 5 -> output: 22
Here is my code so far:
I have some unfinished work with the targetCell (I still wonder how to get its coordinates dynamically in a loop, so that each cell with a larger value than the previous turns to a targetCell.) Also I'm stuck with using the directions I just created. Any hints would be useful for me to further develop the task.
Scanner scanner = new Scanner(System.in);
String input = scanner.nextLine();
String[] my_array = input.split(" ");
int[] array = Arrays.stream(my_array).mapToInt(Integer::parseInt).toArray();
int n = array[0]; // rows of matrix
int m = array[1]; // cols of matrix
int[][] matrix = new int[n][m];
for (int i = 0; i < n; i++) {
String line = scanner.nextLine();
String[] numbers = line.split(" ");
matrix[i] = new int[m];
for (int j = 0; j < m; j++) {
matrix[i][j] = Integer.parseInt(numbers[j]);
}
}
int startPoint = 0;
int currentRow = 0;
int currentCol = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (matrix[i][j] == 0) {
startPoint = matrix[i][j];
currentRow = i;
currentCol = j;
}
}
}
int target1 = 0;
int target2 = 0;
int targetCell = 0;
target1 = Math.max(matrix[currentRow - 1][currentCol], matrix[currentRow + 1][currentCol]);
target2 = Math.max(matrix[currentRow][currentCol - 1], matrix[currentRow][currentCol + 1]);
targetCell = Math.max(target1, target2);
System.out.println(targetCell);
int hDirection = 1;
if (targetCol < currentCol) {
hDirection = -1;
}
int vDirection = 1;
if (targetRow < currentRow) {
vDirection = -1;
}
}
}
}
(Can't comment so will use an answer for now. Sorry)
My first thought would be to keep a global variable for the run so that when a coin is collected, it is added to its current value; similar to how you would keep score in games like Tetris. That's assuming I've read it right.
So something like:
private static int current_score = 0; //Assuming no use of objects so using static
Couldn't understand the sample input in this example. If you could give a three turn scenario of what the final score would be, I could give you better insight.

Creating a multi-dimensional String array from a method array parameter

I am attempting to solve a semi-difficult problem in which I am attempting to create an array and return a 3 dimensional array based on the parameter which happens to be a 2 dimensional int array. The array I'm attempting to return is a String array of 3 dimensions. So here is the code:
public class Displaydata {
static String[][][] makeArray(int[][] dimensions) {
String myArray[][][];
for (int i = 0; i < dimensions.length; i++) {
for (int j = 0; j < dimensions[i].length; j++) {
myArray[][][] = new String[i][j][]; //getting error here.
}
}
return myArray;
}
static void printArray(String[][][] a) {
for (int i = 0; i < a.length; i++) {
System.out.println("\nrow_" + i);
for (int j = 0; j < a[i].length; j++) {
System.out.print( "\t");
for (int k = 0; k < a[i][j].length; k++)
System.out.print(a[i][j][k] + " ");
System.out.println();
}
}
}
public static void main(String[] args) {
int [][] dim = new int[5][];
dim[0] = new int[2];
dim[1] = new int[4];
dim[2] = new int[1];
dim[3] = new int[7];
dim[4] = new int[13];
dim[0][0] = 4;
dim[0][1] = 8;
dim[1][0] = 5;
dim[1][1] = 6;
dim[1][2] = 2;
dim[1][3] = 7;
dim[2][0] = 11;
for (int i = 0; i < dim[3].length;i++)
dim[3][i] = 2*i+1;
for (int i = 0; i < dim[4].length;i++)
dim[4][i] = 26- 2*i;
String[][][] threeDee = makeArray(dim);
printArray(threeDee);
}
}
As you can see from the source code, I'm getting an error when I try to create an instance of my 3-dimensional array which I'm attempting to return. I'm supposed to create a three dimensional array with the number of top-level rows determined by the length of dimensions and, for each top-level row i, the number of second-level rows is determined by the length of dimensions[i]. The number of columns in second-level row j of top-level row i is determined by the value of dimensions[i][j]. The value of each array element is the concatenation of its top-level row index with its second-level row index with its column index, where indices are represented by letters : ‘A’ for 0, ‘B’ for 1 etc. (Of course, this will only be true if the indices don’t exceed 25.) I don't necessarily know where I'm going wrong. Thanks!
You should not be initializing the array on every iteration of the loop. Initialize it once outside the loop and then populate it inside the loop.
static String[][][] makeArray(int[][] dimensions) {
String[][][] myArray = new String[25][25][1];
for (int i = 0; i < dimensions.length; i++) {
for (int j = 0; j < dimensions[i].length; j++) {
myArray[i][j][0] = i + "," + j;
}
}
return myArray;
}
I just plugged in values for the size of the first two dimensions, you will need to calculate them based on what you put in there. The 'i' value will always be dimensions.length but the 'j' value will be the largest value returned from dimensions[0].length -> dimensions[n-1].length where 'n' is the number of elements in the second dimension.
Also you will need to set up a way to convert the numbers in 'i' and 'j' to letters, maybe use a Map.
I guess you should initialize the array as
myArray = new String[i][j][]; //getting error here.
I think
myArray[][][] = new String[i][j][]; //getting error here.
should be:
myArray[i][j] = new String[5]; // I have no idea how big you want to go.
And then you can fill in each element of you inner-most array like such:
myArray[i][j][0] = "first item";
myArray[i][j][1] = "second string";
...
I think you should just change that line to:
myArray = new String[i][j][]; //look ma! no compiler error
Also, you would need to initialize myArray to something sensible (perhaps null?)

2D bucket sort issue

Please dont let the length of this post scare you! Okay so here is the prompt I am currently working on:
"Write a class named BucketSort containing a method called sort that:
a) Place each value of the one-dimensional array into a row of the bucket array, based on the value’s “ones” (rightmost) digit. For example, 97 is placed in row 7, 3 is placed in row 3 an 100 is placed in row 0. This procedure is called a distribution pass.
b) Loop through the bucket array row by row, and copy the values back to the original array. This procedure is called a gathering pass. The new order of the preceding values in the one-dimensional array is 100, 3 and 97.
c) Repeat this process for each subsequent digit position (tens, hundreds, thousands, etc.) On the second (tens digit) pass, 100 is placed in row 0, 3 is placed in row 0 (because 3 has no tens digit) and 97 is placed in row 9. After the gathering pass, the order of the values in the one-dimensional array is 100, 3 and 97. On the third (hundreds digit) pass, 100 is placed in row 1, 3 is placed in row 0 and 97 is placed in row 0 (after the 3) After this last gathering pass, the original array is in sorted order. being sorted.
This sorting technique provides better performance than a bubble sort,but requires much more memory—the bubble sort requires space for only one additional element of data. This comparison is an example of the space/time trade-off: The bucket sort uses more memory than the bubble sort, but performs better. This version of the bucket sort requires copying all the data back to the original array on each pass. Another possibility is to create a second two-dimensional bucket array and repeatedly swap the data between the two bucket arrays. The two-dimensional array of buckets is 10 times the length of the integer array"
A bit of a mouth full I know. Below is my code thus far, but I can't figure out why it will not print in the correct order and I think it is time for fresh eyes. Any ideas are appreciated, thanks!
import java.util.Arrays;
public class BucketSort_main {
public static void main(String[] args)
{
int[] numbers = new int [5];
int[] tnumbers = new int [500];
int [][] bucket = new int [10][numbers.length];
int [] a = new int [10];
int count = 0;
int divisor = 1;
int cnt = 1;
boolean moreDigits = true;
for (int s = 0; s < 10; s++)
{
a[s] = 0;
}
for (int b = 0; b < numbers.length; b++)
{
numbers [b] = (int)(Math.random()*2000);
tnumbers [b] = numbers [b];
}
int[] tmpSort = new int[10];
while (moreDigits)
{
moreDigits = false;
for (int i = 0; i < tmpSort.length; i++)
{
tmpSort[i]= -1; // hint hint
}
for (int i = 0; i < numbers.length; i++)
{
int tmp = tnumbers[i] / divisor;
if (tmp/10 != 0)
{
moreDigits = true;
}
int digit = tmp % 10;
tmpSort[digit] = tnumbers[i]; // hint hint
System.out.println("Number["+i+"], Digit "+cnt+" is "+digit + ". Full number = " + tnumbers[i]);
bucket [digit][a[digit]] = tnumbers[i];
System.out.println ("Digit " + digit + " going to slot " + a[digit] + ". " + bucket[digit][a[digit]]);
System.out.println (" ");
a[digit]++;
}
cnt++;
divisor *= 10;
for (int x = 0; x < 10; x++)
{
a [x] = 0;
for (int y = 0; y < numbers.length; y++)
{
if (bucket[x][y] != 0)
{
tnumbers [y] = 0;
tnumbers [y] = bucket[x][y];
bucket[x][y] = 0;
}
}
}
}
for (int o = 0; o < numbers.length; o++)
{
System.out.println (tnumbers[o]);
}
}
}
The Problem is here:
for (int x = 0; x < 10; x++)
{
a [x] = 0;
for (int y = 0; y < numbers.length; y++)
{
if (bucket[x][y] != 0)
{
tnumbers [y] = 0;
tnumbers [y] = bucket[x][y];
bucket[x][y] = 0;
}
}
}
You are using the same y to get values from the bucket and assign values to tnumbers. So, when you loop through y the second time you are starting over again at tnumbers[0], tnumbers[1], etc...
Fix this issue and your code works fine.

2D Array in Java with number manipulation

My goal is to
Create a 5x5 array and fill it with random integers in the range of 1 to 25.
Print this original array
Process the array, counting the number of odds, evens, and summing all of the elements in the array.
Print the total odds, evens, and the sum.
Im not sure how to do it and my teacher is very confused and cannot help me. I was wondering if i could get some guidance.
Here is my code:
public class Processing {
public static void main(String[] args) {
Random Random = new Random();
int[][] Processing = new int[5][5];
for (int x = 0; x < 5; x++) {
int number = Random.nextInt(25);
Processing[x] = number;
}
for (int i = 0; i < 5; i++) {
Processing[i] = new int[10];
}
}
}
Please follow naming conventions for your variables. See here: http://en.wikipedia.org/wiki/Naming_convention_(programming)#Java
Anyways, you have to nest your loops as follows:
for(int i = 0; i < 5; i ++) {
for(int j = 0; j < 5; j++) {
yourArray[i][j] = random.nextInt(25);
}
}
i is the row number and j is the column number, so this would assign values to each element in a row, then move on to the next row.
I'm guessing this is homework so I won't just give away the answer to your other questions, but to set you on the right track, here's how you would print the elements. Again, use two nested loops:
for(int i = 0; i < 5; i ++) {
for(int j = 0; j < 5; j++) {
// print elements in one row in a single line
System.out.print(yourArray[i][j] + " ");
}
System.out.println(); //return to the next line to print next row.
}

Categories