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]
public class FunWithArrays {
public static void main(String[] args) {
int[] myFunArray = {7, 10, 3, 0, 615, -1000};
int i;
//minimum
int min;
min = myFunArray[0];
for (i=0; i < myFunArray. length; i++) {
if (myFunArray[i] < min) {
min = myFunArray[i];
}
}
//maximum
int max;
max= myFunArray[0];
for (i=1; i < myFunArray. length; i++) {
if (myFunArray[i] > max) {
max = myFunArray[i];
}
}
System.out.println("minimum = " + min + " maximum = " + max);
//mean without outliers
double noOutliersMean = 0;
for (i=0; i < myFunArray.length; i++){
noOutliersMean = ((sum - (max + min)) /myFunArray.length );
if ( myFunArray.length < 3){
System.out.println("not enough numbers");
}
}
System.out.println("Mean without Outliers: " +noOutliersMean);
//Array reversed
int[] reversed = myFunArray;
for(int i1 = reversed.length - 1; i1 >= 0 ; i1--) {
System.out.println( "Reversed " + reversed[i1]);
}
}
}
For the mean without the outliers (max and min) the answer should be 5 my line of code gives me 1.333. What am i doing wrong?
2nd question regarding the array reversed, when printed out it gives me the right answer but each number on a separate line. How do i get it to be on 1 line in the format of ; reversed: [-1000,615,0,3,10,7]
the answer to your second question is don't print using
println
, just use print
The code should be:
System.our.print("Reversed: [")
for(int i1 = reversed.length - 1; i1 >= 0 ; i1--) {
System.out.print(reversed[i1]);
if(i1>0){
System.our.print(",");
}
}
System.out.print("]");
To answer your first question you need to provide the following:
How you are calculating sum, max and min. Even though you have mentioned without max and min.. you still are using it in your code
Think about the logic of the code when you manipulated the array...
you will see that the mean with no min or max is the same as:
the mean excluding the elements at index0 and index length-1 if the array were sorted, so that is what you have to do
sort the array
loop excluding 1st and last
calculate the mean
Example:
int[] myFunArray = { 7, 10, 3, 0, 615, -1000 };
// unsorted { 7, 10, 3, 0, 615, -1000 };
// sorted { -1000, 0, 3, 7, 10, 615 };
Arrays.sort(myFunArray);
System.out.println(Arrays.toString(myFunArray));
int acumm = 0;
double mean = 0.0;
for (int i = 1; i < myFunArray.length - 1; i++) {
acumm += myFunArray[i];
}
mean = acumm / (myFunArray.length - 2);
System.out.println(mean);
I have a number x=27 and an array of values int[] y=[15,20,25,30,35,40,45].
How can I compare the two in order to get the first 3 numbers from the array that are bigger than x?
I guess a for loop needs to be used here but I'm a beginner so this is beyond me.
There is a working solution using arrays:
public class Main {
public static void main(String[] args) {
int x = 27;
int[] y = {15, 20, 25, 30, 35, 40, 45};
int[] result = new int[3];
int z = 0;
for(int i = 0; i < y.length; i++) {
if(y[i] > x && z < 3) {
result[z] = y[i];
z++;
}
}
System.out.println(result[0] + " " + result[1] + " " + result[2]); //Print 30 35 40
}
}
If the array is sorted and contains no duplicates (as is the case in the example given), you can get this result out quickly using a binary search:
int pos = java.util.Arrays.binarySearch(
y,
0/*inclusive as per function spec*/,
y.length/*exlusive as per function spec*/,
x
);
if (pos >= 0){
// x is found at position 'pos', but we want elements greater than this.
++pos;
} else {
int i = -pos - 1; // this is where x would be inserted to preserve sortedness
pos = i + 1;
}
// ToDo - your elements are at `pos`, `pos + 1`, and `pos + 2`,
// subject to your not running over the end of the array `y`.
try this:
int[] y={15,30,29,30,35,40,45};
int x=27;
for(int i = 0,index = 3; i < y.length; i++){
if(i < index && y[i] > x){
System.out.print(y[i]+" ");
}
}
output:
30 29
Fascinating how everybody sticks to loops... Stream-based, we have 2016 after all:
int[] y = {15, 20, 25, 30, 35, 40, 45};
int x = 17;
IntStream.of(y).filter(v -> v > x).limit(3).forEach(System.out::println);
Say I have 10 integer variables, x1 to x10.
I have an integer array, as follows:
Int[] countup = new Int[10];
I would like to specify the elements of the array as follows:
countup[0] = x1;
countup[1] = x1 + x2;
countup[2] = x1 + x2 + x3;
And so on until countup[9] is the sum of x1 to x10.
I could do this manually if it was just 10 elements, but in the actual program I'm writing, there's over 100 elements of the array. Is there any way to set the variables of this array quickly?
A for loop is your best bet, simply put your 10 (or 100) integers into an array of it's own, then loop over your second array referencing indexes of the first array:
int[] xNumbers = { x1, x2, x3, ... x10 };
int[] countup = new int[10];
//Set the 0 index so we don't have to do extra check inside the for loop
//for out-of-bounds exception
countup[0] = xNumbers[0];
for (int i = 1; i < 10; i++) {
//countup[i-1] is why we set index 0 outside of the loop
countup[i] = xNumbers[i] + countup[i-1];
}
since countup[i-1] is the sum of the previous numbers, the previous additions are already done for you. In case you don't know what a for loop is, more information can be found here
Succinctly:
int[] xNums = { /*your x numbers here*/ };
int[] resultArray = new int[xNums.length];
for(int n = 0; n < xNums.length; n++)
{
for(int i = 0; i <= n; i++)
{
resultArray[n]+=xNums[i];
}
}
Hope that makes sense!
I wanted to find a way to do it in Java 8, and the other answer is probably better:
Here's what I have, but it seems redundant and a waste of time, but I'm unfamiliar with Java 8:
public static void main(String[] args) {
int[] arr = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int length = arr.length;
for (int i = 1; i < length; i++) {
System.out.println(Arrays.toString(Arrays.copyOfRange(arr, 0, i + 1)));
arr[i] = Arrays.stream(Arrays.copyOfRange(arr, 0, i + 1)).sum();
}
System.out.println(Arrays.toString(arr));
}
arr[9] is [1, 3, 7, 15, 31, 63, 127, 255, 511, 1023]
I believe I also interpreted the question differently. I think he wanted in index[i] the sum of all previous elements.
If my interpretation of your question is correct, to do it without Java 8, using 2 loops:
int[] array = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int length = array.length;
for(int i = 1; i < length; i++) {
int sumSoFar = 0;
for(int j = 0; j <= i; j ++) {
sumSoFar += array[j];
}
array[i] = sumSoFar;
}