fill two dimensional array with unique random number with java - java

Is there any way to fill two dimensional array with unique random number ? I tried so much but all of my tries are failed .
I can do this
ArrayList<Integer> list = new ArrayList<>();
for (int i = 1; i < 26; i++) { //element will be in range (1,25)
list.add(i);
}
Collections.shuffle(list);
for (int j = 0; j < 5; j++) {
System.out.print(list.get(j) + " ");
}
System.out.println();

If you wanted to print a 5x5 matrix of numbers from the List, you just need two layers of for loops. See the below code in action here.
ArrayList<Integer> list = new ArrayList<>();
for (int i = 1; i < 26; i++) { // element will be in range (1,25)
list.add(i);
}
Collections.shuffle(list);
for (int j = 0; j < 5; j++) {
for (int k = 0; k < 5; k++) {
System.out.format("%3d ", list.get(j * 5 + k));
}
System.out.println();
}
System.out.println();
Example Output:
3 4 23 18 15
1 8 20 6 7
5 21 19 2 24
17 13 22 16 25
14 9 12 10 11

I guess you can use combination of library which generates the random number and hashset. Hashset to remember the random number generated so far, and if duplicate is generated, you re-generate until it gives you the unseen number

Try this.
static List<List<Integer>> uniqueRandomNumbers(int height, int width) {
List<Integer> list = IntStream.rangeClosed(1, height * width)
.boxed()
.collect(Collectors.toList());
Collections.shuffle(list);
List<List<Integer>> matrix = IntStream.range(0, height)
.mapToObj(i -> list.subList(i * width, (i + 1) * width))
.collect(Collectors.toList());
return matrix;
}
and
List<List<Integer>> matrix = uniqueRandomNumbers(5, 5);
for (List<Integer> list : matrix)
System.out.println(list);
result
[16, 4, 15, 14, 25]
[19, 11, 6, 21, 9]
[17, 20, 3, 1, 5]
[10, 7, 22, 18, 2]
[12, 13, 24, 23, 8]

Does this can help ?
public static void main(String[] args)
{
// declare arrays
int[][] ticketInfo;
String[][] seatingChart;
// create arrays
ticketInfo = new int [2][3];
seatingChart = new String [3][2];
// initialize the array elements
ticketInfo[0][0] = 15;
ticketInfo[0][1] = 10;
ticketInfo[0][2] = 15;
ticketInfo[1][0] = 25;
ticketInfo[1][1] = 20;
ticketInfo[1][2] = 25;
seatingChart[0][0] = "Jamal";
seatingChart[0][1] = "Maria";
seatingChart[1][0] = "Jacob";
seatingChart[1][1] = "Suzy";
seatingChart[2][0] = "Emma";
seatingChart[2][1] = "Luke";
// print the contents
System.out.println(ticketInfo);
System.out.println(seatingChart);
}

Related

How to find first 5 highest value in a two dimensional array?

I have a two dimensional integer array. Row and Column information (locations of numbers) is important for me. So, I don't want to sort an array (matrix actually). How can I find the highest 5 value from this two dimensional array?
Here is my code:
for (int row = 0; row < matirx.length; row++) {
for (int col = 0; col < matirx[row].length; col++) {
if (matirx[row][col] > maxValue) {
maxValue = matirx[row][col];
}
}
}
First, I went for a streams solution that is very similar to other Answers. I didn't like the boxing and unboxing variations, but since IntStream doesn't have a fancy method that makes sorting with a Comparator straight out of the box, the IntStream has to be converted into a Stream in order to sort the values in reverse order. I didn't think it was important to return an int[] array, since we're only really interested in the values.
public static Integer[] streamIt(int[][] matrix, int n){
Integer[] result =
Arrays.stream(matrix) // stream the arrays
// This is the same as using .flatMaptoInt(..) and then .boxed()
.flatMap(a -> Arrays.stream(a) // stream the array in arrays
.mapToObj(i -> Integer.valueOf(i))) // turn the ints into Integers
.sorted(Comparator.reverseOrder()) // sort by higest values
.limit(n) // only pick n
.toArray(i -> new Integer[i]); // put then in Integer array
return result;
}
If you want them in an int[] array instead, look at the Answer by shadow.sabre that uses mapToInt() do to that.
While the streams solution is very neat and clean looking, I felt that the problem was really just to get the set of highest values, so inserting them into a standard java sorted Set made sense to me. I start off by inserting the values into the set until there are 5 elements in there. Then I check to see if the new value is higher than the lowest value, and if so, I just remove the lowest value while inserting the new one. Finding the lowest value is easy when using TreeSet as it's a sorted set.
The trick is to also check that the new value isn't already in the set. If there's already 5, 4, 3, 2, 1 in the set, and the new value is 5, then I don't want to remove the lowest value 1, since adding the new value wouldn't actually add any new elements to the Set. Remember a Set cannot contain duplicate values:
public static Set<Integer> useSet(int[][] matrix, int n){
TreeSet<Integer> max = new TreeSet<>(Comparator.<Integer>naturalOrder().reversed());
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
// Keep adding values until there's n elements in the Set
if (max.size() < n) {
max.add(matrix[i][j]);
} else {
// if the new value is higher than the lowest value
// ..and the new values isn't already there.
if (max.last() < matrix[i][j] && !max.contains(matrix[i][j])) {
max.pollLast();
max.add(matrix[i][j]);
}
}
}
}
return max;
}
Note that this solution obviously never contains the same values, but always the top distinct ones.
Looking at the set solution it was easy to add the additional functionality of keeping track of where in the matrix the values were found. I created a class, Element, to contain the value and its location. Every element in the matrix that's to be inserted into the TreeSet is created as an Element.
The Element needs to either implement Comparable or the TreeSet has to be initialized with a Comparator in order to sort the elements. This example of Element has both, and I just used the static Comparator in the implementation of compareTo(Element that) to make it a Comparable<Element>. Normally you'd implement the class with private fields using getters to fetch the values, but for this purpose is seemed a little verbose. Making the fields final also ensures the class is immutable so I have no scruples about it.
Since the comparison is done using both the value and the location, every element from the matrix will be distinct:
class Element implements Comparable<Element> {
final int value;
final int x;
final int y;
static Comparator<Element> comparator =
Comparator.comparing((Element e) -> e.value)
.thenComparing((Element e) -> e.x)
.thenComparing((Element e) -> e.y)
.reversed();
Element(int value, int x, int y) {
this.value = value;
this.x = x;
this.y = y;
}
public int compareTo(Element that){
return comparator.compare(this, that);
}
public String toString(){
return value + " at [" + x + "][" + y + "]";
}
}
If the Element didn't implement the Comparable interface, this would be the initialization of the TreeSet:
TreeSet<Element> maxElement = new TreeSet<>(Element.comparator);
But since Element does implement the Comparable interface, the set implementation can be initialized without it:
public static Set<Element> useSetElements(int[][] matrix, int n){
TreeSet<Element> maxElement = new TreeSet<>();
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
if (maxElement.size() < n) {
maxElement.add(new Element(matrix[i][j],i,j));
} else {
if (maxElement.last().value < matrix[i][j]) {
maxElement.pollLast();
maxElement.add(new Element(matrix[i][j],i,j));
}
}
}
}
return maxElement;
}
Note that because every element is distinct, there's no need to also check that the new value isn't already in the set.
Running the three solutions with given input:
int n = 5;
int[][] matrix = {{16, -20, 22, 19},
{ 2, 5, 6, 8},
{17, 25, 16, 19},
{ 7, 18, 4, 17}};
System.out.println("streamIt: \n "
+ Arrays.toString(streamIt(matrix,n)));
System.out.println("useSet: \n "
+ useSet(matrix,n));
System.out.println("useSetElements: \n "
+ useSetElements(matrix,n));
..gives this:
streamIt:
[25, 22, 19, 19, 18]
useSet:
[25, 22, 19, 18, 17]
useSetElements:
[25 at [2][1], 22 at [0][2], 19 at [2][3], 19 at [0][3], 18 at [3][1]]
But what about Performance..?
The three different implementations had me wondering about the performance, so I added a method to time the execution:
static void timeMethod(Runnable toRun){
long start = System.nanoTime();
try{
toRun.run();
} finally {
long end = System.nanoTime();
System.out.println(" Time: " + (end - start)/1.0e6 + " miliseconds");
}
}
And ran the three solutions:
timeMethod(() -> System.out.println("streamIt: \n "
+ Arrays.toString(streamIt(matrix,n))));
timeMethod(() -> System.out.println("useSet: \n "
+ useSet(matrix,n)));
timeMethod(() -> System.out.println("useSetElements: \n "
+ useSetElements(matrix,n)));
..giving this result:
streamIt:
[25, 22, 19, 19, 18]
Time: 1.2759 miliseconds
useSet:
[25, 22, 19, 18, 17]
Time: 0.9343 miliseconds
useSetElements:
[25 at [2][1], 22 at [0][2], 19 at [2][3], 19 at [0][3], 18 at [3][1]]
Time: 1.16 miliseconds
It seems that the three solutions have roughly the same performance. The streams solution seems slightly slower. The Set solution looks promising, expect the solution using Element seems to take a toll. But to look at it more deeply I decided to run them on a much larger matrix, which I build using random integers:
Random random = new Random();
int[][] largerMatrix =
IntStream.range(0,10000) // 10000 on the first dimension
.mapToObj(i -> random.ints(0,128) // values between 0 and 128 (not included)
.limit(10000) // 10000 on the second dimension
.toArray()) // make the second 1D arrays
.toArray(int[][]::new); // put them into a 2D array
Running the test with a 10000 by 10000 matrix:
timeMethod(() -> System.out.println("streamIt: \n "
+ Arrays.toString(streamIt(largerMatrix,n))));
timeMethod(() -> System.out.println("useSet: \n "
+ useSet(largerMatrix,n)));
timeMethod(() -> System.out.println("useSetElements: \n "
+ useSetElements(largerMatrix,n)));
..gave this result:
streamIt:
[127, 127, 127, 127, 127]
Time: 90374.6995 miliseconds
useSet:
[127, 126, 125, 124, 123]
Time: 2465.2448 miliseconds
useSetElements:
[127 at [0][310], 127 at [0][277], 127 at [0][260], 127 at [0][81], 127 at [0][61]]
Time: 1839.7323 miliseconds
Here the streams solution seems incredibly slow! The Element solution is the winner of the two Set solutions. I expect it's due to the fact that Elements are only created when they're needed for inserting into the Set and it's doing a straight up int comparison, while the other Set solution is unboxing every time the values are compared. I didn't further test my hypothesis though.
My curiosity of the other solutions in this thread got me testing out those as well. The solutions tested were:
Answer by Arvind Kumar Avinash
Answer by Anurag Jain
Answer by Michael Chatiskatzi
Running the tests on both the small and the large array:
System.out.println("--- Testing performance ---");
timeMethod(() -> System.out.println("ArvindKumarAvinash: \n "
+ Arrays.toString(ArvindKumarAvinash(matrix,n))));
timeMethod(() -> System.out.println("AnuragJain: \n "
+ AnuragJain(matrix,n)));
timeMethod(() -> System.out.println("MichaelChatiskatzi: \n "
+ Arrays.toString(MichaelChatiskatzi(matrix,n))));
System.out.println();
System.out.println("--- Testing performance with largeMatrix---");
timeMethod(() -> System.out.println("ArvindKumarAvinash: \n "
+ Arrays.toString(ArvindKumarAvinash(largerMatrix,n))));
timeMethod(() -> System.out.println("AnuragJain: \n "
+ AnuragJain(largerMatrix,n)));
timeMethod(() -> System.out.println("MichaelChatiskatzi: \n "
+ Arrays.toString(MichaelChatiskatzi(largerMatrix,n))));
..gave these results:
--- Testing performance ---
ArvindKumarAvinash:
[25, 22, 19, 19, 18]
Time: 0.9076 miliseconds
AnuragJain:
[25, 22, 19, 19, 18]
Time: 6.2277 miliseconds
MichaelChatiskatzi:
[18, 19, 19, 22, 25]
Time: 1.2204 miliseconds
--- Testing performance with largeMatrix---
ArvindKumarAvinash:
[127, 127, 127, 127, 127]
Time: 3381.1387 miliseconds
AnuragJain:
[127, 127, 127, 127, 127]
Time: 120244.7063 miliseconds
MichaelChatiskatzi:
[127, 127, 127, 127, 127]
Time: 51.4259 miliseconds
It seems that solutions using streams are not very performant at all. Michael Chatiskatzi's solution is by far the better performant one.
All the code
If you want to run it yourself, here a complete class for copy'n'paste'n'run:
import java.util.Arrays;
import java.util.Comparator;
import java.util.stream.IntStream;
import java.util.Set;
import java.util.TreeSet;
import java.util.Comparator;
import java.util.Random;
import java.util.List;
import java.util.ArrayList;
import java.util.stream.Collectors;
public class GettingTheTopN {
public static void main(String[] args) {
int n = 5;
int[][] matrix = {{16, -20, 22, 19},
{ 2, 5, 6, 8},
{17, 25, 16, 19},
{ 7, 18, 4, 17}};
System.out.println("streamIt: \n "
+ Arrays.toString(streamIt(matrix,n)));
System.out.println("useSet: \n "
+ useSet(matrix,n));
System.out.println("useSetElements: \n "
+ useSetElements(matrix,n));
System.out.println();
System.out.println("--- Testing performance ---");
timeMethod(() -> System.out.println("streamIt: \n "
+ Arrays.toString(streamIt(matrix,n))));
timeMethod(() -> System.out.println("useSet: \n "
+ useSet(matrix,n)));
timeMethod(() -> System.out.println("useSetElements: \n "
+ useSetElements(matrix,n)));
timeMethod(() -> System.out.println("ArvindKumarAvinash: \n "
+ Arrays.toString(ArvindKumarAvinash(matrix,n))));
timeMethod(() -> System.out.println("AnuragJain: \n "
+ AnuragJain(matrix,n)));
timeMethod(() -> System.out.println("MichaelChatiskatzi: \n "
+ Arrays.toString(MichaelChatiskatzi(matrix,n))));
System.out.println();
System.out.println("--- Testing performance with largeMatrix---");
Random random = new Random();
int[][] largerMatrix =
IntStream.range(0,10000) // 10000 on the first dimension
.mapToObj(i -> random.ints(0,128) // values between 0 and 128 (not included)
.limit(10000) // 10000 on the second dimension
.toArray()) // make the second 1D arrays
.toArray(int[][]::new); // put them into a 2D array
timeMethod(() -> System.out.println("streamIt: \n "
+ Arrays.toString(streamIt(largerMatrix,n))));
timeMethod(() -> System.out.println("useSet: \n "
+ useSet(largerMatrix,n)));
timeMethod(() -> System.out.println("useSetElements: \n "
+ useSetElements(largerMatrix,n)));
timeMethod(() -> System.out.println("ArvindKumarAvinash: \n "
+ Arrays.toString(ArvindKumarAvinash(largerMatrix,n))));
timeMethod(() -> System.out.println("AnuragJain: \n "
+ AnuragJain(largerMatrix,n)));
timeMethod(() -> System.out.println("MichaelChatiskatzi: \n "
+ Arrays.toString(MichaelChatiskatzi(largerMatrix,n))));
}
public static Integer[] streamIt(int[][] matrix, int n){
Integer[] result =
Arrays.stream(matrix) // stream the arrays
// This is the same as using .flatMaptoInt(..) and then .boxed()
.flatMap(a -> Arrays.stream(a) // stream the array in arrays
.mapToObj(i -> Integer.valueOf(i))) // turn the ints into Integers
.sorted(Comparator.reverseOrder()) // sort by higest values
.limit(n) // only pick n
.toArray(i -> new Integer[i]); // put then in Integer array
return result;
}
public static Set<Integer> useSet(int[][] matrix, int n){
TreeSet<Integer> max = new TreeSet<>(Comparator.<Integer>naturalOrder().reversed());
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
// Keep adding values until there's n elements in the Set
if (max.size() < n) {
max.add(matrix[i][j]);
} else {
// if the new value is higher than the lowest value
// ..and the new values isn't already there.
if (max.last() < matrix[i][j] && !max.contains(matrix[i][j])) {
max.pollLast();
max.add(matrix[i][j]);
}
}
}
}
return max;
}
public static Set<Element> useSetElements(int[][] matrix, int n){
TreeSet<Element> maxElement = new TreeSet<>();
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
if (maxElement.size() < n) {
maxElement.add(new Element(matrix[i][j],i,j));
} else {
if (maxElement.last().value < matrix[i][j]) {
maxElement.pollLast();
maxElement.add(new Element(matrix[i][j],i,j));
}
}
}
}
return maxElement;
}
// ----------------- Performance
static void timeMethod(Runnable toRun){
long start = System.nanoTime();
try{
toRun.run();
} finally {
long end = System.nanoTime();
System.out.println(" Time: " + (end - start)/1.0e6 + " miliseconds");
}
}
// [Answer to "How to find first 5 highest value in a two dimensional array?"](https://stackoverflow.com/a/65374950/12695027) by [Arvind Kumar Avinash](https://stackoverflow.com/users/10819573/arvind-kumar-avinash)
static int[] ArvindKumarAvinash(int[][] matrix, int MAX_N) {
// Find count as the total number of elements
int count = 0, row, col;
for (row = 0; row < matrix.length; row++) {
count += matrix[row].length;
}
// Create flattened = new int[count] and fill it with all elements of matrix[][]
int[] flattened = new int[count];
int i = 0;
for (row = 0; row < matrix.length; row++) {
for (col = 0; col < matrix[row].length; col++) {
flattened[i++] = matrix[row][col];
}
}
// Create max = new int[MAX_N] to store maximum n numbers.
// Also, create maxPos = new int[MAX_N] to store the position of the maximum numbers.
int[] max = new int[MAX_N];
int[] maxPos = new int[MAX_N];
// Loop MAX_N times. In each iteration, assume flattened[0] is the largest number.
for (i = 0; i < max.length; i++) {
max[i] = flattened[0];
for (int j = 1; j < flattened.length; j++) {
// If flattened[j] >= max[i], check if the position, j has already been
// processed. If not assign flattened[j] to max[i] and j to maxPos[i].
if (flattened[j] >= max[i]) {
boolean posAlreadyProcessed = false;
for (int k = 0; k <= i; k++) {
if (maxPos[k] == j) {
posAlreadyProcessed = true;
break;
}
}
if (!posAlreadyProcessed) {
max[i] = flattened[j];
maxPos[i] = j;
}
}
}
}
return max;
// System.out.println("Largest " + MAX_N + " values: " + Arrays.toString(max));
}
// [Answer to "How to find first 5 highest value in a two dimensional array?"](https://stackoverflow.com/a/65380541/12695027) by [Anurag Jain](https://stackoverflow.com/users/5825625/anurag-jain)
static List<Integer> AnuragJain(int[][] matrix, int n) {
List<Integer> allVal = new ArrayList<>();
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
allVal.add(matrix[i][j]);
}
}
allVal = allVal.stream()
.sorted(Comparator.reverseOrder())
.limit(n).collect(Collectors.toList());
return allVal;
// System.out.println(allVal);
}
// [Answer to "How to find first 5 highest value in a two dimensional array?"](https://stackoverflow.com/a/65379921/12695027) by [Michael Chatiskatzi](https://stackoverflow.com/users/11263320/michael-chatiskatzi)
static int[] MichaelChatiskatzi(int[][] matrix, int n) {
// int[] highestNumbers = new int[5];
int[] highestNumbers = new int[n];
Arrays.fill(highestNumbers, Integer.MIN_VALUE);
for (int row = 0; row < matrix.length; row++) {
for (int column = 0; column < matrix[row].length; column++) {
int currentEntry = matrix[row][column];
if (currentEntry > highestNumbers[0]) {
highestNumbers[0] = currentEntry;
Arrays.sort(highestNumbers);
}
}
}
return highestNumbers;
// System.out.println(Arrays.toString(highestNumbers));
}
}
// -------------------------------------------
// -------------------------------------------
class Element implements Comparable<Element> {
final int value;
final int x;
final int y;
static Comparator<Element> comparator =
Comparator.comparing((Element e) -> e.value)
.thenComparing((Element e) -> e.x)
.thenComparing((Element e) -> e.y)
.reversed();
Element(int value, int x, int y) {
this.value = value;
this.x = x;
this.y = y;
}
public int compareTo(Element that){
return comparator.compare(this, that);
}
public String toString(){
return value + " at [" + x + "][" + y + "]";
}
}
Let MAX_N = 5.
Find count as the total number of elements in matrix[][].
Create flattened = new int[count] and fill it with all elements of matrix[][].
Create max = new int[MAX_N] to store maximum n numbers. Also, create maxPos = new int[MAX_N] to store the position of the maximum numbers.
Loop MAX_N times and in each iteration, assume flattened[0] is the largest number.
If flattened[j] >= max[i], check if the position, j has already been processed. If not assign flattened[j] to max[i] and j to maxPos[i].
Demo:
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
final int MAX_N = 5;
int[][] matrix = {
{16, -20, 11, 19},
{2, 5, 6, 8},
{17, 25, 16, 19},
{7, 17, 4, 17}};
// Find count as the total number of elements
int count = 0, row, col;
for (row = 0; row < matrix.length; row++) {
count += matrix[row].length;
}
// Create flattened = new int[count] and
// fill it with all elements of matrix[][]
int[] flattened = new int[count];
int i = 0;
for (row = 0; row < matrix.length; row++) {
for (col = 0; col < matrix[row].length; col++) {
flattened[i++] = matrix[row][col];
}
}
// Create max = new int[MAX_N] to store maximum
// n numbers. Also, create maxPos = new int[MAX_N]
// to store the position of the maximum numbers.
int[] max = new int[MAX_N];
int[] maxPos = new int[MAX_N];
// Loop MAX_N times. In each iteration,
// assume flattened[0] is the largest number.
for (i = 0; i < max.length; i++) {
max[i] = flattened[0];
for (int j = 1; j < flattened.length; j++) {
// If flattened[j] >= max[i], check if the
// position, j has already been processed.
// If not assign flattened[j] to max[i]
// and j to maxPos[i].
if (flattened[j] >= max[i]) {
boolean posAlreadyProcessed = false;
for (int k = 0; k <= i; k++) {
if (maxPos[k] == j) {
posAlreadyProcessed = true;
break;
}
}
if (!posAlreadyProcessed) {
max[i] = flattened[j];
maxPos[i] = j;
}
}
}
}
System.out.println("Largest " + MAX_N +
" values: " + Arrays.toString(max));
}
}
Output:
Largest 5 values: [25, 19, 19, 17, 17]
With Java8 streams it can be done with this (one) line of code. It will leave the original matrix untouched.
Arrays.stream(matrix) // create a stream of the matrix
.flatMapToInt(Arrays::stream) //Reduce 2d matrix to 1d
.boxed() //Convert int to Integer so we can sort reversed order
.sorted(Collections.reverseOrder()) //sort array in reversed order highest first
.limit(5) //Limit stream to 5 entries, the five top results
.forEach(System.out::println); //Print the result
Now that the question is open again, I will present my comment as an answer.
Instead of iterating over the same matrix multiple times I fill the int[] highestNumbers with Integer.MIN_VALUE, iterate over the matrix once, and replace the smallest entry of max each time the current integer is greater, by updating the first entry of highestNumbers and sort it.
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int[][] matrix = {
{10, -5, 15},
{8, 20, 12},
{27, -3, 14},
{7, 17, 4}};
int[] highestNumbers = new int[5];
Arrays.fill(highestNumbers, Integer.MIN_VALUE);
for (int row = 0; row < matrix.length; row++) {
for (int column = 0; column < matrix[row].length; column++) {
int currentEntry = matrix[row][column];
if (currentEntry > highestNumbers[0]) {
highestNumbers[0] = currentEntry;
Arrays.sort(highestNumbers);
}
}
}
System.out.println(Arrays.toString(highestNumbers));
}
}
Output:
[14, 15, 17, 20, 27]
Without sorting array itself, you can make sorted the stream over this array. Or you can implement a kind of selection sort in descending order. These two code examples do the same thing - find the first 5 highest distinct values in 2D array, if they are present:
int[][] arr = {
{1, 4, 7, 7},
{2, 5, 8, 3},
{5, 5, 1, 2},
{3, 6, 0, 9}};
int[] max = Arrays.stream(arr)
.flatMapToInt(Arrays::stream)
.boxed().sorted(Comparator.reverseOrder())
.mapToInt(Integer::intValue)
.distinct()
.limit(5)
.toArray();
System.out.println(Arrays.toString(max)); // [9, 8, 7, 6, 5]
int[][] arr = {
{1, 4, 7, 7},
{2, 5, 8, 3},
{5, 5, 1, 2},
{3, 6, 0, 9}};
int[] max = new int[5];
for (int m = 0; m < max.length; m++) {
int prev_max = m > 0 ? max[m - 1] : Integer.MAX_VALUE;
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
if (arr[i][j] > max[m] && prev_max > arr[i][j]) {
max[m] = arr[i][j];
}
}
}
}
System.out.println(Arrays.toString(max)); // [9, 8, 7, 6, 5]
See also: Selection sort of array
You can use below way this will give you below benefits:
Keeping very simple logic, As you want highest 5 values and you will not loose any index location/order for existing array,
Using this you will get better performance,
Clean Code.
public static void main(String[] args) {
int[][] matrix = {
{10, -5, 15},
{8, 20, 12},
{27, -3, 14},
{7, 17, 4}};
List<Integer> allVal = new ArrayList<>();
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
allVal.add(matrix[i][j]);
}
}
allVal = allVal.stream()
.sorted(Comparator.reverseOrder())
.limit(5)
.collect(Collectors.toList());
System.out.println(allVal);
}
Output:
[27, 20, 17, 15, 14]

Print only the numbers, which have been changed

I got curious about a Merge-sorting code.
Description:
This code creates two auxillary arrays left and right and store alternate array elements in them and then copying all elements of left and right subarrays back to original array and printing them. So instead of printing back to the original array, how would it be possible to only print the moved numbers?
class Project {
static void join(int arr[], int left[], int right[],int l, int m, int r){
int i;
for (i = 0; i <= m - l; i++)
arr[i] = left[i];
for (int j = 0; j < r - m; j++)
arr[i + j] = right[j];
}
static void split(int arr[], int left[], int right[],int l, int m, int r) {
for (int i = 0; i <= m - l; i++)
left[i] = arr[i * 2];
for (int i = 0; i < r - m; i++)
right[i] = arr[i * 2 + 1];
}
static void generateWorstCase(int arr[], int l, int r) {
if (l < r) {
int m = l + (r - l) / 2;
int[] left = new int[m - l + 1];
int[] right = new int[r - m];
split(arr, left, right, l, m, r);
generateWorstCase(left, l, m);
generateWorstCase(right, m + 1, r);
join(arr, left, right, l, m, r);
}
}
public static void main (String[] args) {
int arr[] = { 10, 11, 12, 13, 14, 15, 16 };
int n = arr.length;
System.out.println("Sorted array is");
System.out.println(Arrays.toString(arr));
generateWorstCase(arr, 0, n - 1);
System.out.println("\nInput array that will result in worst case of merge sort is: \n");
System.out.println(Arrays.toString(arr));
}
}
Here's the output:
System.out.println(Arrays.toString(arr));
My question is..
I would ask, can you, based on the code, only have the output as, like the numbers being moved, and not the entire array?
Example:
The input is:
{ 10 20 30 40 50 }
The output is:
{ 10 50 30 20 40 }
My Desired Output:
{ 50 20 40 }
(The number of inputs varies according to the number of output)..
How would this happen?
Do it as follows:
public static void main(String[] args) {
int arr[] = { 10, 11, 12, 13, 14, 15, 16 };
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < arr.length; i++) {
map.put(arr[i], i);
}
int n = arr.length;
System.out.println("Sorted array is");
System.out.println(Arrays.toString(arr));
generateWorstCase(arr, 0, n - 1);
List<Integer> list = new ArrayList<Integer>();
for (int i = 0; i < arr.length; i++) {
if (map.get(arr[i]) != i) {
list.add(arr[i]);
}
}
System.out.println("\nInput array that will result in worst case of merge sort is: \n" + list);
}
Output:
Sorted array is
[10, 11, 12, 13, 14, 15, 16]
Input array that will result in worst case of merge sort is:
[14, 16, 11, 13]
Another solution:
public static void main(String[] args) {
int arr[] = { 10, 11, 12, 13, 14, 15, 16 };
int[] original = Arrays.copyOf(arr, arr.length);
int n = arr.length;
System.out.println("Sorted array is");
System.out.println(Arrays.toString(arr));
generateWorstCase(arr, 0, n - 1);
List<Integer> list = new ArrayList<Integer>();
for (int i = 0; i < arr.length; i++) {
if (original[i] != arr[i]) {
list.add(arr[i]);
}
}
System.out.println("\nInput array that will result in worst case of merge sort is: \n" + list);
}
Output:
Sorted array is
[10, 11, 12, 13, 14, 15, 16]
Input array that will result in worst case of merge sort is:
[14, 16, 11, 13]
[Update]
You have requested to change the format of the output so that the numbers are not bounded by []. Note that this is how Arrays.toString or List::toString returns the string. If you do not want an array or a List, you can do it simply as:
public static void main(String[] args) {
int arr[] = { 10, 11, 12, 13, 14, 15, 16 };
int[] original = Arrays.copyOf(arr, arr.length);
int n = arr.length;
System.out.println("Sorted array is");
System.out.println(Arrays.toString(arr));
generateWorstCase(arr, 0, n - 1);
StringBuilder s = new StringBuilder();
int i;
for (i = 0; i < arr.length; i++) {
if (original[i] != arr[i]) {
s.append(arr[i]).append(", ");
}
}
String output = s.substring(0, s.lastIndexOf(","));
System.out.println("\nInput array that will result in worst case of merge sort is: \n" + output);
}
Output:
Sorted array is
[10, 11, 12, 13, 14, 15, 16]
Input array that will result in worst case of merge sort is:
14, 16, 11, 13
If you want to change the format of the output while keeping the List, you can do it as follows:
public static void main(String[] args) {
int arr[] = { 10, 11, 12, 13, 14, 15, 16 };
int[] original = Arrays.copyOf(arr, arr.length);
int n = arr.length;
System.out.println("Sorted array is");
System.out.println(Arrays.toString(arr));
generateWorstCase(arr, 0, n - 1);
List<Integer> list = new ArrayList<Integer>();
for (int i = 0; i < arr.length; i++) {
if (original[i] != arr[i]) {
list.add(arr[i]);
}
}
System.out.println("\nInput array that will result in worst case of merge sort is: \n"
+ list.toString().replace("[", "").replace("]", ""));
}
Output:
Sorted array is
[10, 11, 12, 13, 14, 15, 16]
Input array that will result in worst case of merge sort is:
14, 16, 11, 13
Iterate over both arrays simultaneously. If input[i] is not equal to output[i] then it has been moved.
List<Integer> moved = new ArrayList<>();
for (int i = 0; i < input.length; i++) {
if (input[i] != output[i]) {
moved.add(input[i]);
}
}

Summing Numbers in an Array Greater than an Inputted Value

Need to add all numbers in an array that is greater than an inputted number. The seed is just so the output can be replicated.
Example:
[12,16,45,3,32]
Inputted Value: 30
Output:
77
import java.util.*;
public class SumAbove {
public static void main(String[] args) {
Scanner scnr = new Scanner(System.in);
int seed = scnr.nextInt();
Random rand = new Random(seed);
System.out.println("Enter a positive integer between 1-100 to search above:");
int minVal = scnr.nextInt();
int[] arr = new int[rand.nextInt(100)+1];
for (int i=0; i<arr.length; i++) {
arr[i] = rand.nextInt(100)+1;
}
System.out.println(Arrays.toString(arr));
int sum = 0;
for (int i=0; i<arr.length; i++) {
if (arr[i]>minVal) {
sum += i;
}
}
System.out.println(sum);
}
}
Instead of sum += i; you want sum += arr[i]; (as already noted), you also only need one loop (since you know the minimum before the first loop). Like,
int minVal = scnr.nextInt(), sum = 0;
int[] arr = new int[rand.nextInt(100) + 1];
for (int i = 0; i < arr.length; i++) {
arr[i] = rand.nextInt(100) + 1;
if (arr[i] > minVal) {
sum += arr[i];
}
}
System.out.println(Arrays.toString(arr));
System.out.println(sum);
Replace sum += i with sum += arr[i].
The variable i is just the position. arr[i] is the value at that position.
public static void main(String[] args) {
int nums[] = { 12, 16, 45, 3, 32 };
int value;
int sum = 0;
System.out.println("Enter a positive integer between 1-100 to search above: ");
Scanner sc = new Scanner(System.in);
value = sc.nextInt();
for (int i = 0; i < nums.length; i++) {
if (nums[i] > value)
sum = nums[i] + sum;
}
System.out.println(sum);
}
Here is how you can do it with streams in Java 8+.
int nValues = 5;
int minValue = 1;
int maxValue = 30;
Random r = new Random();
for (int i = 0; i < 10; i++) {
int[] values = r.ints(nValues, minValue, maxValue + 1).toArray();
// min to sum is the threshold
int minToSum = r.nextInt(7) + 10; // between 10 an 16 inclusive
int sum = Arrays.stream(values).filter(m -> m > minToSum).sum();
System.out.println("sum = " + sum + " for greater than " + minToSum
+ " : " + Arrays.toString(values));
}
The following output.
sum = 65 for values greater than 11 : [2, 10, 14, 23, 28]
sum = 92 for values greater than 10 : [13, 18, 15, 19, 27]
sum = 94 for values greater than 12 : [25, 6, 14, 25, 30]
sum = 54 for values greater than 10 : [14, 8, 14, 26, 5]
sum = 22 for values greater than 15 : [15, 8, 13, 22, 14]
sum = 28 for values greater than 13 : [3, 28, 9, 6, 5]
sum = 87 for values greater than 13 : [5, 18, 25, 21, 23]
sum = 31 for values greater than 13 : [16, 7, 12, 2, 15]
sum = 42 for values greater than 15 : [7, 22, 20, 10, 5]
sum = 40 for values greater than 12 : [2, 2, 13, 27, 9]

Efficient Data Structure for the average of a matrix

I have an array list.
Its value is
arrlist[0] = 1 2 3
arrlist[1] = 4 5 6
arrlist[2] = 7 8 9
arrlist[3] = 10 11 12
arrlist[4] = 13 14 15
WHat I want is getting the avg of : 1,4,7,10,13. Then an avg of 2,5,8,11,14 and so on
and the resulting arraylist should contain only one string like 7,8,9 (the avg of all 5 columns )
The nos would be random.
Which would be the best efficient manner. ??
I thought of a method where I store every element in a new array list but the looping would be much big.
Can anyone suggestme an efficient way.
The way I am thinking is : Just a psuedo code
arraylist newarrylist = new arraylist ();
for(int j=0;j<arrlist.size*arrlist[0].size;j++) // as each arrlist would have same elements
{
newarrylist[j] = arrlist(j).sunstring(j); // means will get the substring, first column, then second..
}
Like people said, premature optimization is the root of all evil; unless of course your array is big (e.g. 10000 rows * 10000 columns).
In any case, there are not that many options in calculating averages!
What I'd do is something like this (take this more as a pseudo-code, I have not debugged it; also, make sure there are no integer overflows):
int[] columnAverages = new int[width];
for (int row = 0; row < height; row++)
for (int column = 0; column < width; column++)
{
int value = (parse the next integer here);
columnAverages[column] += value;
}
for (int column = 0; column < width; column++)
columnAverages[column] /= height;
Hope this helps
The data structure used in here is an array list (collection) of an array of integers.
There you go, a solution for your problem:
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
/**
*
* #author Mohamed Ennahdi El Idrissi
* 25 February 2014.
*
*/
public class User3345483 {
/*
* arrlist[0] = 1 2 3
* arrlist[1] = 4 5 6
* arrlist[2] = 7 8 9
* arrlist[3] = 10 11 12
* arrlist[4] = 13 14 15
*/
static List<Integer[]> arrliste = new ArrayList<Integer[]>();
public static void main(String[] args) {
/*
arr = new Integer[]{1, 2, 3};
arrliste.add(arr);
arr = new Integer[]{4, 5, 6};
arrliste.add(arr);
arr = new Integer[]{7, 8, 9};
arrliste.add(arr);
arr = new Integer[]{10, 11, 12};
arrliste.add(arr);
arr = new Integer[]{13, 14, 15};
arrliste.add(arr);
*/
initArray();
initArray();
initArray();
initArray();
initArray();
displayArray();
Integer[] arr;
arr = new Integer[3];
int avg;
for (int i = 0; i < arr.length; i++) {
avg = 0;
for (int j = 0; j < arrliste.size(); j++) {
avg += ((Integer[]) arrliste.get(j))[i];
}
avg = avg/arrliste.size();
System.out.println("Average Column " + i + ": " +avg);
arr[i] = avg;
}
}
static void initArray() {
Integer[] arr = new Integer[3];
for (int i = 0; i < arr.length; i++) {
arr[i] = new Random().nextInt(100);
}
arrliste.add(arr);
}
static void displayArray() {
System.out.println("Values of the Populated Array:");
for (Integer[] integer : arrliste) {
for (int i = 0; i < integer.length; i++) {
System.out.print(integer[i] + "\t");
}
System.out.println();
}
}
}

How to access each row in Triangular numbers?

Given triangular numbers are as follows:
4
5 3
9 2 21
1 46 12 8
.... upto n rows.
Need to get the highest number from each row and sum it up.
I'm not able to figure out where and how to put all the n rows (like 2D array) and how to select each row from it.
If you can use a List<List<Integer>> instead of array, then your job would be quite easy by using Collections.max method:
// The below syntax is called `double braces initialization`.
List<List<Integer>> triangularNumber = new ArrayList<List<Integer>>() {
{
// Add inner lists to the outer list.
add(Arrays.asList(4));
add(Arrays.asList(5, 3));
add(Arrays.asList(9, 2, 21));
add(Arrays.asList(1, 46, 12, 8));
}
};
int sum = 0;
for (List<Integer> innerList: triangularNumber) {
sum += Collections.max(innerList);
}
System.out.println(sum);
public static void main(String[] args) {
int[][] matrix = { { 4 }, { 5, 3 }, { 9, 2, 21 }, { 1, 46, 12, 8 } };
int sum = 0;
for (int i = 0; i < matrix.length; i++) {
int maxInRow = matrix[i][0];
for (int j = 0; j < matrix[i].length; j++) {
System.out.println(matrix[i][j]);
if (maxInRow < matrix[i][j]) {
maxInRow = matrix[i][j];
}
}
sum = sum + maxInRow;
}
System.out.println(sum);
}
Try this:
Why not work with a map? If you need to know each row's index you can do it like this:
Map<Integer, List<Integer>> numbers = new HashMap<Integer, List<Integer>();
as for finding the maximum one can use:
Collections.max(...)
JDK doc
This should do the trick.

Categories

Resources