import java.util.*;
import java.util.Arrays;
public class EmployeeWeeklyHours{
public static void main(String[] args) {
int[][] employeeHours= new int[][] {
{ 2, 4, 3, 4, 5, 8, 8},
{ 7, 3, 4, 3, 3, 4, 4},
{ 3, 3, 4, 3, 3, 2, 2},
{ 9, 3, 4, 7, 3, 4, 1},
{ 3, 5, 4, 3, 6, 3, 8},
{ 3, 4, 4, 6, 3, 4, 4},
{ 3, 7, 4, 8, 3, 8, 4},
{ 6, 3, 5, 9, 2, 7, 9}};
int [] finalHours = new int[8];
for (int i = 0; i < finalHours.length; i++) {
int total = 0;
for (int j = 0; j < finalHours.length - 1; j++) {
total += employeeHours[i][j];
finalHours[i] = total;
}
}
java.util.Arrays.sort(finalHours);
int[] sort = new int[finalHours.length];
for (int i = 0; i < finalHours.length; i++)
sort[i] = finalHours[i];
for (int i = 7; i > -1; i--)
System.out.println(sort[i]);
}
}
Employee 0: 2 4 3 4 5 8 8
Employee 1: 7 3 4 3 3 4 4
Employee 2: 3 3 4 3 3 2 2
Employee 3: 9 3 4 7 3 4 1
Employee 4: 3 5 4 3 6 3 8
Employee 5: 3 4 4 6 3 4 4
Employee 6: 3 7 4 8 3 8 4
Employee 7: 6 3 5 9 2 7 9
As you can see from my code, I am supposed to list the total hours worked for each employee in descending order. However, I seem to be stumped on a way to show the Employee Numbers next to their total hours.
E.G. "Employee 7 worked 42 hours.
Is there any way that I can list the Employee Numbers alongside the sorted numbers without hard coding them in? I feel like there is a simple answer to my question, but nothing comes to mind right now.
One solution would be using a TreeMap since it sorts on the keys automatically.
TreeMap<Integer, Integer> treeMap =
new TreeMap<Integer, Integer>(Collections.reverseOrder());
for (int i = 0; i < finalHours.length; i++) {
treeMap.put(finalHours[i], i);
}
for (Entry<Integer, Integer> entry : treeMap.entrySet()) {
System.out.println( "Employee " + entry.getValue() + " worked " + entry.getKey() + " hours.");
}
for (int i=0; i < finalHours.length; i++) {
System.out.println(String.format("Employee %d worked %d hours.", i, finalHours[i]));
}
And since you mentioned hardcoding, when you write a loop, rather than putting a magic "7" in there, use variables like finalHours.length or employeeHours.length. The same principle holds in general: refer to variables even when you "know" what the value is going to be.
if you want this code ?
import java.util.*;
import java.util.Arrays;
public class EmployeeWeeklyHours{
public static void main(String[] args) {
int[][] employeeHours= new int[][]{
{ 2, 4, 3, 4, 5, 8, 8},
{ 7, 3, 4, 3, 3, 4, 4},
{ 3, 3, 4, 3, 3, 2, 2},
{ 9, 3, 4, 7, 3, 4, 1},
{ 3, 5, 4, 3, 6, 3, 8},
{ 3, 4, 4, 6, 3, 4, 4},
{ 3, 7, 4, 8, 3, 8, 4},
{ 6, 3, 5, 9, 2, 7, 9}};
String [] finalHours = new String[8];
for (int i = 0; i < finalHours.length; i++)
{
int total = 0;
for (int j = 0; j < finalHours.length-1; j++)
{
total += employeeHours[i][j];
finalHours[i] = "Employee "+ i+" worked "+total + "hours";
}
}
java.util.Arrays.sort(finalHours);
String[] sort = new String[finalHours.length];
for (int i = 0; i < finalHours.length; i++)
{
sort[i] = finalHours[i];
}
for (int i = 7; i > -1; i--)
{
System.out.println(sort[i]);
}
}
}
result is
Employee 7 worked 41hours
Employee 6 worked 37hours
Employee 5 worked 28hours
Employee 4 worked 32hours
Employee 3 worked 31hours
Employee 2 worked 20hours
Employee 1 worked 28hours
Employee 0 worked 34hours
use int[] alternative String[] so you can obatin that result.
bye.
Related
How can I add the values in the arrNumbers that exceed 6 to add to a new array starting from the last value and ending at the first.
This is what I have written, but does not produce the right output.
int[] arrNumbers = new int[] { 1, 2, 3, 4, 5, 6, 1, 2 };
int[] newArrNumbers = new int[6];
for(int i = 0; i < arrNumbers.length ; i++){
newArrNumbers[i % 6] += arrNumbers[i];
}
The actual output:
newArrNumbers = [2, 4, 3, 4, 5, 6]
However, I want the output to ADD to the LAST VALUE in the arrNumbers, going from right to left, not left to right. So result should be:
newArrNumbers = [1, 2, 3, 4, 7, 7]
Try this.
int[] arrNumbers = new int[] { 1, 2, 3, 4, 5, 6, 1, 2 };
int[] newArrNumbers = new int[6];
for(int i = 0; i < arrNumbers.length ; i++){
newArrNumbers[i < 6 ? i : (6 - (i % 6) - 1)] += arrNumbers[i];
}
System.out.println(Arrays.toString(newArrNumbers));
output:
[1, 2, 3, 4, 7, 7]
I am trying to print out the 'middle' of the 2D array (a). For example, for given arrays in my code, I would like to print:
[3,4,5,6]
[4,5,6,7]
However I was only able to print out the 'middle' values. I would like to modify the 2D array (a) in the method inner and print it in main instead, and not use System.out.println in the nested for loop. How would I go about doing this?
Here is my code:
public static int[][] inner(int[][] a) {
int rowL = a.length - 1;
int colL = a[1].length - 1;
for (int row = 1; row < rowL; row++) {
for (int col = 1; col < colL; col++) {
//System.out.print(a[row][col]);
a = new int[row][col];
}
System.out.println();
}
return a;
}
public static void main(String[] args) {
int[][] a = {
{1, 2, 3, 4, 5, 6},
{2, 3, 4, 5, 6, 7},
{3, 4, 5, 6, 7, 8},
{4, 5, 6, 7, 8, 9}};
for (int[] row : a) {
System.out.println(Arrays.toString(row));
}
System.out.println();
for (int[] row : inner(a)) {
System.out.println(Arrays.toString(row));
}
}
Create a new array outside the loop and then fill that array inside the loop by translating the indices between the two arrays:
public static int[][] inner (int[][] a) {
int rowL = a.length - 1;
int colL = a[1].length -1;
int[][] ret = new int[rowL - 1][colL - 1];
for (int row = 1; row < rowL; row++) {
for (int col = 1; col < colL ; col++) {
ret[row - 1][col - 1] = a[row][col];
}
}
return ret;
}
If you just want to print the middle values (my definition for this code example is: middle = full array minus first and last element), you can make use of a StringBuilder:
public static void main(String[] args) {
int[][] a = {
{ 1, 2, 3, 4, 5, 6 },
{ 2, 3, 4, 5, 6, 7 },
{ 3, 4, 5, 6, 7, 8 },
{ 4, 5, 6, 7, 8, 9 }
};
for (int[] b : a) {
// create a String output for each inner array
StringBuilder outputBuilder = new StringBuilder();
// append an introducing bracket
outputBuilder.append("[");
// make the values to be printed ignore the first and last element
for (int i = 1; i < b.length - 1; i++) {
if (i < b.length - 2) {
/*
* append a comma plus whitespace
* if the element is not the last one to be printed
*/
outputBuilder.append(b[i]).append(", ");
} else {
// just append the last one without trailing comma plus whitespace
outputBuilder.append(b[i]);
}
}
// append a closing bracket
outputBuilder.append("]");
// print the result
System.out.println(outputBuilder.toString());
}
}
The output will be
[2, 3, 4, 5]
[3, 4, 5, 6]
[4, 5, 6, 7]
[5, 6, 7, 8]
You can use Arrays.stream(T[],int,int) method to iterate over a given range of an array:
int[][] arr = {
{1, 2, 3, 4, 5, 6},
{2, 3, 4, 5, 6, 7},
{3, 4, 5, 6, 7, 8},
{4, 5, 6, 7, 8, 9}};
int[][] middle = Arrays.stream(arr, 1, arr.length - 1)
.map(row -> Arrays.stream(row, 1, row.length - 1)
.toArray())
.toArray(int[][]::new);
// output
Arrays.stream(middle).map(Arrays::toString).forEach(System.out::println);
[3, 4, 5, 6]
[4, 5, 6, 7]
I want to display something like this:
1 {1,2,3,4,5,6,7,8,9}
2 {1,2,3,4,5,6,7,8,9}
...
9 {1,2,3,4,5,6,7,8,9}
Nothing works
int[][] areas = new int[9][9];
for(int j=0; j<=8; j++)
{ // do i need to initialize here first array? something like areas [j][] = j ;
// how can i do that?
for(int i=0; i<=8; i++)
{
areas[j][i] = i;
Log.d("tiles", String.valueOf(areas[j][i])); // here i get from 1 to 9, 9 times
}
Log.d("area", String.valueOf(areas[j]));
//here is the problem
//i want to show 1 {for all tiles for this 1 area}, than 2 {for all tiles for
//this 2 area}... for each but it only display an address
}
I want to have control when I want to go to area 6 to tile 5 for example
Try Arrays.toString
int[] arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
String s = Arrays.toString(arr).replace("[", "{").replace("]", "}");
for (int i = 1; i <= arr.length; i++) {
System.out.println(i + " " + s);
}
Ouput
1 {1, 2, 3, 4, 5, 6, 7, 8, 9}
2 {1, 2, 3, 4, 5, 6, 7, 8, 9}
3 {1, 2, 3, 4, 5, 6, 7, 8, 9}
4 {1, 2, 3, 4, 5, 6, 7, 8, 9}
5 {1, 2, 3, 4, 5, 6, 7, 8, 9}
6 {1, 2, 3, 4, 5, 6, 7, 8, 9}
7 {1, 2, 3, 4, 5, 6, 7, 8, 9}
8 {1, 2, 3, 4, 5, 6, 7, 8, 9}
9 {1, 2, 3, 4, 5, 6, 7, 8, 9}
int[][] areas = new int[10][10];
for (int j = 0; j <= 8; j++) {
System.out.print(j + 1);
System.out.print("{");
for (int i = 0; i <= 8; i++) {
areas[j][i] = i;
if (areas[j][i] < 8) {
System.out.print(String.valueOf(areas[j][i] + 1) + ","); // here i get from 1 to 9, 9 times
} else {
System.out.print(String.valueOf(areas[j][i] + 1));
}
}
System.out.print("}");
}
OUTPUT
1{1,2,3,4,5,6,7,8,9}2{1,2,3,4,5,6,7,8,9}3{1,2,3,4,5,6,7,8,9}4{1,2,3,4,5,6,7,8,9}5{1,2,3,4,5,6,7,8,9}6{1,2,3,4,5,6,7,8,9}7{1,2,3,4,5,6,7,8,9}8{1,2,3,4,5,6,7,8,9}9{1,2,3,4,5,6,7,8,9}
import java.util.Random;
public class Sudoku {
int[][] SquareNumbers = {
{ 4, 3, 5, 8, 7, 6, 1, 2, 9 }, { 8, 7, 6, 2, 1, 9, 3, 4, 5 }, { 2, 1, 9, 4, 3, 5, 7, 8, 6 },
{ 5, 2, 3, 6, 4, 7, 8, 9, 1 }, { 9, 8, 1, 5, 2, 3, 4, 6, 7 }, { 6, 4, 7, 9, 8, 1, 2, 5, 3 },
{ 7, 5, 4, 1, 6, 8, 9, 3, 2 }, { 3, 9, 2, 7, 5, 4, 6, 1, 8 }, { 1, 6, 8, 3, 9, 2, 5, 7, 4 } };
Random Digits = new Random(); // random numbers to exchange Rows
Random HiddenNumbers = new Random();
int Grid[][] = new int[9][9];
public int[][] Generator() {
for (int x = 0; x < Digits.nextInt(); x++) {
for (int da = 0; da < 3; da++) {
}
}
return SquareNumbers;
}
int[][] Hide() {
for (int i = 0; i < 9; i++)
for (int j = 0; j < 9; j++)
Grid[i][j] = SquareNumbers[i][j];
int Row, Columns, Concealer;
Concealer = 55 + Digits.nextInt(1);
for (int i = 0; i < Concealer; i++) {
Row = HiddenNumbers.nextInt(9);
Columns = HiddenNumbers.nextInt(9);
Grid[Row][Columns] = -1;
}
return Grid;
}
public int[][] getSquareNumbers() {
return SquareNumbers;
}
public void setSquareNumbers(int[][] SquareNumbers) {
this.SquareNumbers = SquareNumbers;
}
private static Sudoku instance = null;
protected Sudoku() {
// Exists only to defeat instantiation.
}
public static Sudoku getInstance() {
if (instance == null) {
instance = new Sudoku();
}
return instance;
}
}
Instead of a double array list, is there a way to randomize it so it works like a Sudoku game? As in it has no duplicates within columns or rows and every three by three smaller grid uses a number once?
One method for generating random sudoku puzzles would be as follows:
Generate a random puzzle satisfying the constraints of a sudoku puzzle
Randomly swap digits (e.g. replace 2s with 3s, 7s with 1s, etc)
Randomly swap columns or rows within their set of 3 (e.g. swap the first and third column, or the 5th and 6th)
Randomly switch sets of 3 columns or rows
with another set of columns.
While these will look like different puzzles, they will in fact, all be isotropic latin squares (i.e. all equivalent since they can be reduced to the same puzzle by reordering rows/columns).
If you want a more random solution, this may have already been answered here: https://stackoverflow.com/a/6964044/2471910
I have a simple array, sort of like this:
1 2 3 4 5 6 7 8 9
6 2 7 2 9 6 8 10 5
2 6 4 7 8 4 3 2 5
9 8 7 5 9 7 4 1 10
5 3 6 8 2 7 3 7 2
So, let's call this matrix[5][9]. I wish to now remove every row within this matrix that contains a certain value, in this case 10, so I am left with...
1 2 3 4 5 6 7 8 9
2 6 4 7 8 4 3 2 5
5 3 6 8 2 7 3 7 2
Here's a sample class you can run that I believe does what you're looking for. Removing rows from 2D arrays is tricky business because like #KalebBrasee said, you can't really "remove" them, but rather you have to make a whole new 2D array instead. Hope this helps!
import java.util.ArrayList;
import java.util.List;
public class Matrix {
private double[][] data;
public Matrix(double[][] data) {
int r = data.length;
int c = data[0].length;
this.data = new double[r][c];
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
this.data[i][j] = data[i][j];
}
}
}
/* convenience method for getting a
string representation of matrix */
public String toString() {
StringBuilder sb = new StringBuilder(1024);
for (double[] row : this.data) {
for (double val : row) {
sb.append(val);
sb.append(" ");
}
sb.append("\n");
}
return (sb.toString());
}
public void removeRowsWithValue(final double value) {
/* Use an array list to track of the rows we're going to want to
keep...arraylist makes it easy to grow dynamically so we don't
need to know up front how many rows we're keeping */
List<double[]> rowsToKeep = new ArrayList<double[]>(this.data.length);
for (double[] row : this.data) {
/* If you download Apache Commons, it has built-in array search
methods so you don't have to write your own */
boolean found = false;
for (double testValue : row) {
/* Using == to compares doubles is generally a bad idea
since they can be represented slightly off their actual
value in memory */
if (Double.compare(value, testValue) == 0) {
found = true;
break;
}
}
/* if we didn't find our value in the current row,
that must mean its a row we keep */
if (!found) {
rowsToKeep.add(row);
}
}
/* now that we know what rows we want to keep, make our
new 2D array with only those rows */
this.data = new double[rowsToKeep.size()][];
for (int i = 0; i < rowsToKeep.size(); i++) {
this.data[i] = rowsToKeep.get(i);
}
}
public static void main(String[] args) {
double[][] test = {
{1, 2, 3, 4, 5, 6, 7, 8, 9},
{6, 2, 7, 2, 9, 6, 8, 10, 5},
{2, 6, 4, 7, 8, 4, 3, 2, 5},
{9, 8, 7, 5, 9, 7, 4, 1, 10},
{5, 3, 6, 8, 2, 7, 3, 7, 2}};
//make the original array and print it out
Matrix m = new Matrix(test);
System.out.println(m);
//remove rows with the value "10" and then reprint the array
m.removeRowsWithValue(10);
System.out.println(m);
}
}
Use System.arraycopy or use java.util.List instead of arrays. ArrayList has fast access to random elements and a slow remove method, it's the opposite with LinkedList. You have to choose for yourself.
At the and you have to recreate the array and discard the old one. Changing the dimension of an existing array is not possible - if want this type of datastructure, then you should build the matrix based on Collections (ArrayList<ArrayList<Double>>), there you can remove a row easily.
Back to arrays - the idea is to collect all rows (double[] arrays) that you want to keep, create a result array with those rows and replace the old one with the new on on Matrix:
public void doSomethingWith(Matrix in) {
List<double[]> survivingRows = new ArrayList<double[]>();
for (double[] row:in.getRows()) {
if (isAGoodOne(row)) {
survivingRows.add(row);
}
}
double[][] result = new double[survivingRows][];
for (int i = 0; i < result.length; i++) {
result[i] = survivingRows.get(i);
}
in.setArray(result);
}
You can't remove elements from the Java built-in array data structure. You'll have to create a new array that has a length one less than the first array, and copy all the arrays into that array EXCEPT the one you want to remove.
My java syntax is a little rusty, but the following, if treated as pseudocode will work
public Matrix removeRows(Matrix input) {
int[][] output = new int[input.numRows][input.numColumns]();
int i = 0;
for (int[] row : input.rows()) { // Matrix.rows() is a method that returns an array of all the rows in the matrix
if (!row.contains(10)) {
output[i] = row;
}
}
return output
My take:
import java.util.Arrays;
public class RemoveArrayRow {
private static <T> T[] concat(T[] a, T[] b) {
final int alen = a.length;
final int blen = b.length;
if (alen == 0) {
return b;
}
if (blen == 0) {
return a;
}
final T[] result = (T[]) java.lang.reflect.Array.newInstance(a.getClass().getComponentType(), alen + blen);
System.arraycopy(a, 0, result, 0, alen);
System.arraycopy(b, 0, result, alen, blen);
return result;
}
public static void main(String[] args) {
double[][] d = { {11, 2, 3, 4, 5, 6, 7, 8, 9, 0},
{12, 2, 3, 4, 5, 6, 7, 8, 9, 1},
{13, 2, 3, 4, 5, 6, 7, 8, 9, 2},
{14, 2, 3, 4, 5, 6, 7, 8, 9, 3},
{15, 2, 3, 4, 5, 6, 7, 8, 9, 4} };
//remove the fourth row:
// (1)
double[][] d1 = concat(Arrays.copyOf(d, 3), Arrays.copyOfRange(d, 4, 5));
// (2)
double[][] d2 = new double[d.length - 1][d[0].length];
System.arraycopy(d, 0, d2, 0, 3);
System.arraycopy(d, 4, d2, 3, 1);
System.out.print(d1.length);
System.out.print(d2.length);
}
}
(1)
If you exclude the concat() function used for concatenating two arrays, it's done in one line:
double[][] d1 = concat(Arrays.copyOf(d, 3), Arrays.copyOfRange(d, 4, 5));
See this question as well. That's where the code for the concat() function comes from.
(2)
This method is faster and only uses already available functions.
Since it cannot avoid creating new 2D array to contain the after-removed data, firstly, create a new 2D int[][] b with same dimension as a[][]. secondly, loop through a[][], assign a to b and move b row up when a contain specific value. and sanity check the last row, which can contain specific data.
public static int[][] remove(int[][] a, int v) {
int r = a.length;
int c = a[0].length;
int[][] b = new int[r][c];
int red = 0;
boolean s = false;
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
b[i - red][j] = a[i][j];
if (a[i][j] == v) {
red += 1;
if(i==r-1){
s = true;
}
break;
}
}
}
//check last row
if(s){
for(int i = r-red;i <r-red +1; i++ )
for (int j = 0; j<c; j++){
b[i][j] = 0;
}
}
return b;
}
public static void main(String[] args){
int[][] a = { {1, 2, 3, 4, 5, 6, 7, 8, 1},
{6, 2, 7, 2, 9, 6, 8, 10, 5},
{2, 6, 4, 7, 8, 4, 2, 2, 5},
{9, 8, 7, 5, 9, 7, 4, 1, 1},
{5, 3, 6, 8, 2, 7, 3, 1, 1} };
print(remove(a, 10));
}
public static void print(int[][] a) {
int r = a.length;
int c = a[0].length;
int red = 0;
for (int i = 0; i < r; i++) {
System.out.printf("\nrow %d, \n", i);
for (int j = 0; j < c; j++) {
System.out.printf("%d, ", a[i][j]);
}
}
}
This may not be an exact solution but a concept of how you can achieve it using System.arraycopy.
In the example below, I want to copy all the rows except the first row. In your case, you can skip those rows which contain 10.
String[][] src = getSheetData(service, spreadSheetId, range);
String[][] dest = new String[src.length-1][src[0].length];
for (int i = 1; i < src.length; i++) {
System.arraycopy(src[i], 0, dest[i-1], 0, src[0].length-1);
}
Reference: https://docs.oracle.com/javase/6/docs/api/java/lang/System.html#arraycopy%28java.lang.Object,%20int,%20java.lang.Object,%20int,%20int%29
You can use IntStream.noneMatch method for this purpose:
int[][] arr1 = {
{1, 2, 3, 4, 5, 6, 7, 8, 9},
{6, 2, 7, 2, 9, 6, 8, 10, 5},
{2, 6, 4, 7, 8, 4, 3, 2, 5},
{9, 8, 7, 5, 9, 7, 4, 1, 10},
{5, 3, 6, 8, 2, 7, 3, 7, 2}};
int[][] arr2 = Arrays.stream(arr1)
.filter(row -> Arrays.stream(row).noneMatch(i -> i == 10))
.toArray(int[][]::new);
// output
Arrays.stream(arr2).map(Arrays::toString).forEach(System.out::println);
Output:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
[2, 6, 4, 7, 8, 4, 3, 2, 5]
[5, 3, 6, 8, 2, 7, 3, 7, 2]