Find max at row and min at cols in a 2D array - java

I need to write a java code that get a 2D array as a matrix and check every rows and columns and find the number that its the max at the rows but the min at the cols.
For example, the 13 is the min at col and max at the row:
I wrote the code but I get lost:
import java.util.Scanner;
public class maxmin {
public static Scanner input = new Scanner(System.in);
public static void main(String[] args) {
System.out.println("enter matrix size ");
int num = input.nextInt();
int num1 = input.nextInt();
maxMin(num, num1);
}
private static void maxMin(int num, int num1) {
int max = 0;
int min = 0;
int[][] matrix = new int[num][num1];
System.out.println("ENTER ARRAY NUMBERS");
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[0].length; j++) {
matrix[i][j] = input.nextInt();
}
}
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[0].length; j++) {
if (matrix[i][j] >= max) {
max = matrix[i][j];
for (int a = 0; a < matrix.length; a++) {
if (matrix[i][a] <= min) {
min = matrix[i][a];
}
if (max == min) {
System.out.println(max);
}
}
}
}
}
}
}

You can use IntStream for this purpose:
int[][] arr = {
{1, 2, 3, 6, 5},
{3, 2, 5, 6, 7},
{5, 6, 7, 8, 9},
{1, 3, 0, 2, 4}};
int num = Arrays
// iterate over the nested arrays,
// i.e. rows of the 2d array
.stream(arr)
// find maximum value of the row
// return IntStream of maximums
.mapToInt(row -> Arrays.stream(row)
// maximum value of the row
.max().orElse(Integer.MIN_VALUE))
// find minimum value of row maximums
.min().orElse(Integer.MIN_VALUE);
// output
System.out.println(num); // 4

So first thing. Since you are trying to find a number that is MAX at row and MIN at column, it means you are trying to find multiple numbers. As such, there should be some resetting code for resetting the max and min in order to find new max and min.
Then, what you need to think about is HOW you are gonna find it. Since it must be max in the column first, you have to iterate all positions in each row first while recording the max position. Then you iterate that particular column associated with the max position in that row. You get it? You ONLY iterate the column again (beside the first time) when you finish an entire row first and know the position.
#Alex Rudenko notes that since there are negative numbers in the matrix, an initial value of max and min should default to
int max = Integer.MIN_VALUE;
int min = Integer.MAX_VALUE;
which is essential for the below code to work.
So the code for the last block should look something like this:
for (int i = 0; i < matrix.length; i++){
for (int j = 0; j < matrix[0].length; j++){
if (matrix[i][j] > max){
max = matrix[i][j];
maxPos = j; //declare this beforehand
}
}
for (int a = 0; a < matrix.length; a++ ){
if( matrix[a][maxPos] < min){
min = matrix[a][maxPos];
}
}
if(max == min) {
System.out.println(matrix[i][maxPos]);
max = Integer.MIN_VALUE;
min = Integer.MAX_VALUE;
}
}
That’s it! There could be something down to avoid repetition on already checked position, but this is the central logic of this operation.
Also, I assume you are only printing the max&min number. You can also save those numbers in an array or something if you need to use it later.
Since you are trying to learn, I would suggest refrain from using advanced methods. This is a helpful basic to solidify you coding muscle.

Related

Product of array in a new array except the current index value

Given an array of integers, create a new array such that each element at index i of the new array is the product of all the numbers in the original array except the one at i.
For example, if our input was [1, 2, 3, 4, 5], the expected output would be [120, 60, 40, 30, 24]. If our input was [3, 2, 1], the expected output would be [2, 3, 6].
Note: Do not use division.
import java.util.Scanner;
public class Productofarray {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int prod = 1, i, j = 0;
System.out.println("How many values do you want to enter");
int n = sc.nextInt();
int a[] = new int[n];
int a2[] = new int[n];
System.out.println("Input " + n + " values:");
for (i = 0; i < n; i++) {
a[i] = sc.nextInt();
}
for (i = 0; i < n; i++) {
inner:
while (j < n) {
if (a[j] == a[i]) {
j++;
continue inner;
}
prod *= a[j];
}
a2[i] = prod;
System.out.println(a2[i]);
}
}
}
I have written this code but the problem is that it is keep on running and it never ends can someone help me what I am doing wrong here.
This should get you closer; as pointed out by Maneesh's answer, you're not checking that you're at the current index i.e i == j instead of a[i]==a[j]. you also do not need the label and it is suggested that you avoid them completely.
for(int i=0; i<n; i++)
{
// this loop can be replaced with a stream.reduce - however that seems to require copying a1 in place to remove the element at index i first as reduce doesn't seem to pass the current index.
for(int j = 0; j < n; j++) {
if(j i) continue;
a2[i] *= a1[j];
}
System.out.println(a2[i]);
}
it took me a second to figure it out but here's a example using the Java 8 Stream APIs:
for(int i=0; i<n; i++) // for i -> n
{
final int currentIndex = i;
a2[i] = IntStream.range(0, a1.length)
.filter(index -> index != currentIndex) // ingore the curent index
.map(index -> a1[index]) // map the remaining indecies to the values
.reduce((subTotal, current) -> subTotal * current); // reduce to a single int through multiplication.
}
System.out.println(a2[i]);
I haven't tested it but it should work (maybe with a tweak or two). The. gist of it is making a new array (IntStream.range) that contains every element of the given array but the one at currentIndex (.filter().map()) and then multiply the elements (reduce(... subTotal * current)). Note that this solution creates a new array for every iteration through the for loop which, with extremely large arrays, is memory-inefficient.
because you are not incrementing j when i!=j. also, you should check for i==j not a[i]==a[j].

How to create an array from a pre-existing array?

New to java and am trying to create a program/method that will take an int array, and return another int array but it replaces the values of the indexes with the value of the elements. (Example {2,1,3} will return {0,0,1,2,2,2}
public static void main(String[] args) {
int[] pracArray = {2, 1, 3};
int sum = 0;
for (int i = 0; i < pracArray.length; i++)
{
sum = sum + pracArray[i];
}
System.out.println("Amount of array indexes: " + sum);
int[] newArray = new int[sum];
System.out.println(Arrays.toString(pracArray));
for (int i = 0; i < pracArray.length; i++)
{
for (int j = 0; j < pracArray[i]; j++)
{
newArray[j] = i;
}
}
System.out.println(Arrays.toString(newArray));
}
}
Currently I am getting [2,2,2,0,0,0]. I have tried changing the how many times each for loop iterates with no avail. I have also tried to make the elements of newArray equal to a counter ( int count = 0; and having count++ in the for loop) since the values of the new array will always be 0 - however many runs.
Given the length of your array is 3, your outer 'i' loop is iterating through the values 0,1,2. That means your inner 'j' loop never writes to index 3,4,5 (hence why they are 0 in the output), and why the first 3 indexes are set to '2' (2 is the last indexed processed in the 'i' loop). Try this instead...
int h = 0;
for (int i = 0; i < pracArray.length; i++)
{
for (int j = 0; j < pracArray[i]; j++)
{
newArray[h] = i;
h++;
}
}

Delete max element in array

Wrote some code to try to find the maximum element in an un-ordered array and then delete it from the array. My first loop has the logic to find the maximum element while the second loop should take in the variable from the first loop, look ahead one space and then insert into the max element.
My below code seems to work for my second idea .. but does not find the right max array element.
My array has the following values {6, 3, 5, 2, 7, 9, 4}. It is finding the max array element to be 7 .. it should be 9.
public void deleteMax() {
// set value for comparison starting from the beginning of the array
int arrayMax = arr[0];
for (int i = 0; i < nElems; i++) {
if (arr[i] > arrayMax) {
arrayMax = arr[i];
for (int k = i; k < nElems; k++) {
arr[k] = arr[k + 1];
nElems--;
break;
}
}
}
}
why not use jQuery $.grep & Math.max like:
var arr = [6, 3, 5, 2, 7, 9, 4];
var maxNum = Math.max.apply(null, arr);
var newArr = $.grep( arr, function( n ) {
return n != maxNum;
});
console.log(newArr);
Fiddle
EDIT:
Well didn't realize you're using Java as the question showed in JavaScript section...
in Java, You can find max number in array like
int maxNum = arr.get(0); // get the first number in array
for (int i = 1; i < arr.length; i++) {
if ( arr.get(i) > maxNum) {
maxNum = array.get(i);
}
}
arr.remove(maxNum);
Well,, you don't need any second loop.
Only one loop and two variables called, f.ex. MaxElementPosition and MaxElementValue, which are updated every time inside the loop if the number on this position is greater than the last MaxElementValue, update both value and position.
While the loop you do need the value for comparing. In the end you only need the position.
Your inner loop is irrelevant, you only have a 1D array, so it makes no sense to do any inner iteration.
If you insist on performing no sorting on the array, then you could do something like this:
public void deleteMax() {
// set value for comparison starting from the beginning of the array
int arrayMax = arr[0];
int maxIndex = 0;
for (int i = 0; i < nElems; i++) {
if (arr[i] > arrayMax) {
arrayMax = arr[i];
maxIndex = i;
}
}
arr.remove(maxIndex);
}
Once the for loop finishes, we remove the item at maxIndex
#Alex is on the right track, but there is no remove function that can be called on an array in java. All that you need is the variable maxIndex that he gets, which of course will be the first occurence of this maximum, so if you need to remove every occurence of the maximum, that would be a different issue. So once you use #Alex code:
int arrayMax = arr[0];
int maxIndex = 0;
for (int i = 0; i < nElems; i++) {
if (arr[i] > arrayMax) {
arrayMax = arr[i];
maxIndex = i;
}
}
This would be much easier if instead of an array, you were to use an ArrayList, in which case the code would look like:
int arrayMax = arr.get(0);
int maxIndex = 0;
for (int i = 0; i < nElems; i++) {
if (arr[i] > arrayMax) {
arrayMax = arr[i];
maxIndex = i;
}
}
arr.remove(maxIndex);
Otherwise you would have to create a temp array to remove the value:
int[] temp = new int[arr.length-1];
for(int i = 0, index = 0; index < nElems; i++, index++)
{
if(index == maxIndex) index++;
temp[i] = arr[index];
}
arr = temp;

Adding the columns of a jagged 2D array

I've looked all over for a good answer, but I was surprised I couldn't find one that accomplished quite what I'm trying to do. I want to create a method that finds a columns sum in a jagged 2D array, regardless of the size, whether it's jagged, etc. Here is my code:
public static int addColumn(int[][] arr, int x) {
int columnSum = 0;
int i = 0;
int j = 0;
int numRows = arr.length;
//add column values to find sum
while (i < numRows) {
while (j < arr.length) {
columnSum = columnSum + arr[i][x];
j++;
i++;
}
}//end while loop
return columSum;
}
So, for example, consider I have the following array:
int[][] arr = {{10, 12, 3}, {4, 5, 6, 8}, {7, 8}};
I want to be able to pass x as 2, and find the sum for Column 3 which would be 9. Or pass x as 3 to find Column 4, which would simply be 8. My code is flawed as I have it now, and I've tried about a hundred things to make it work. This is a homework assignment, so I'm looking for help to understand the logic. I of course keep getting an Out of Bounds Exception when I run the method. I think I'm overthinking it at this point since I don't think this should be too complicated. Can anyone help me out?
I think that your second while loop is making your sum too big. You should only have to iterate over the rows.
while (i < numRows) {
if (x < arr[i].length) {
columnSum += arr[i][x];
}
++i;
}
In Java 8, you can use IntStream for this purpose:
public static int addColumn(int[][] arr, int x) {
// negative column index is passed
if (x < 0) return 0;
// iteration over the rows of a 2d array
return Arrays.stream(arr)
// value in the column, if exists, otherwise 0
.mapToInt(row -> x < row.length ? row[x] : 0)
// sum of the values in the column
.sum();
}
public static void main(String[] args) {
int[][] arr = {{10, 12, 3}, {4, 5, 6, 8}, {7, 8}};
System.out.println(addColumn(arr, 2)); // 9
System.out.println(addColumn(arr, 3)); // 8
System.out.println(addColumn(arr, 4)); // 0
System.out.println(addColumn(arr, -1));// 0
}
I saw the codes above. None of it is the adequate answer since posting here the code which meets the requirement. Code might not look arranged or optimized just because of the lack of time. Thanks.... :)
package LearningJava;
import java.util.Scanner;
public class JaggedSum {
public static void main(String[] args) {
int ik = 0;
int ij = 0;
Scanner scan = new Scanner(System.in);
int p = 0;
int q = 0;
int[][] arr = new int[2][];
System.out.println("Enter the value of column in Row 0 ");
p = scan.nextInt();
System.out.println("Enter the value of column in Row 1 ");
q = scan.nextInt();
arr[0] = new int[p];
arr[1] = new int[q];
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
arr[i][j] = scan.nextInt();
}
}
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
System.out.print(arr[i][j] + " ");
}
System.out.println();
}
if (arr[1].length > arr[0].length) {
int[] columnSum = new int[arr[1].length];
int x;
for (x = 0; x < arr[0].length; x++) {
columnSum[x] = arr[0][x] + arr[1][x];
System.out.println(columnSum[x]);
}
ik = arr[0].length;
for (int j = ik; j < arr[1].length; j++) {
columnSum[j] = arr[1][j];
System.out.println(columnSum[j]);
}
} else {
int[] columnSum = new int[arr[0].length];
int x;
for (x = 0; x < arr[1].length; x++) {
columnSum[x] = arr[0][x] + arr[1][x];
System.out.println(columnSum[x]);
}
ij = arr[1].length;
for (int j = ij; j < arr[0].length; j++) {
columnSum[j] = arr[0][j];
System.out.println(columnSum[j]);
}
}
}
}

Printing out the least occurring elements in an array

OK, so I found this question from a few days ago but it's on hold and it won't let me post anything on it.
***Note: The values or order in the array are completely random. They should also be able to be negative.
Someone recommended this code and was thumbed up for it, but I don't see how this can solve the problem. If one of the least occurring elements isn't at the BEGINNING of the array then this does not work. This is because the maxCount will be equal to array.length and the results array will ALWAYS take the first element in the code written below.
What ways are there to combat this, using simple java such as below? No hash-maps and whatnot. I've been thinking about it for a while but can't really come up with anything. Maybe using a double array to store the count of a certain number? How would you solve this? Any guidance?
public static void main(String[] args)
{
int[] array = { 1, 2, 3, 3, 2, 2, 4, 4, 5, 4 };
int count = 0;
int maxCount = 10;
int[] results = new int[array.length];
int k = 0; // To keep index in 'results'
// Initializing 'results', so when printing, elements that -1 are not part of the result
// If your array also contains negative numbers, change '-1' to another more appropriate
for (int i = 0; i < results.length; i++) {
results[i] = -1;
}
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array.length; j++) {
if (array[j] == array[i]) {
count++;
}
}
if (count <= maxCount) { // <= so it admits number with the SAME number of occurrences
maxCount = count;
results[k++] = array[i]; // Add to 'results' and increase counter 'k'
}
count = 0; // Reset 'count'
}
// Printing result
for (int i : results) {
if (i != -1) {
System.out.println("Element: " + i + ", Number of occurences: " + maxCount);
}
}
}
credit to: https://stackoverflow.com/users/2670792/christian
for the code
I can't thumbs up so I'd just like to say here THANKS EVERYONE WHO ANSWERED.
You can also use an oriented object approach.
First create a class Pair :
class Pair {
int val;
int occ;
public Pair(int val){
this.val = val;
this.occ = 1;
}
public void increaseOcc(){
occ++;
}
#Override
public String toString(){
return this.val+"-"+this.occ;
}
}
Now here's the main:
public static void main(String[] args) {
int[] array = { 1,1, 2, 3, 3, 2, 2, 6, 4, 4, 4 ,0};
Arrays.sort(array);
int currentMin = Integer.MAX_VALUE;
int index = 0;
Pair[] minOcc = new Pair[array.length];
minOcc[index] = new Pair(array[0]);
for(int i = 1; i < array.length; i++){
if(array[i-1] == array[i]){
minOcc[index].increaseOcc();
} else {
currentMin = currentMin > minOcc[index].occ ? minOcc[index].occ : currentMin;
minOcc[++index] = new Pair(array[i]);
}
}
for(Pair p : minOcc){
if(p != null && p.occ == currentMin){
System.out.println(p);
}
}
}
Which outputs:
0-1
6-1
Explanation:
First you sort the array of values. Now you iterate through it.
While the current value is equals to the previous, you increment the number of occurences for this value. Otherwise it means that the current value is different. So in this case you create a new Pair with the new value and one occurence.
During the iteration you will keep track of the minimum number of occurences you seen.
Now you can iterate through your array of Pair and check if for each Pair, it's occurence value is equals to the minimum number of occurences you found.
This algorithm runs in O(nlogn) (due to Arrays.sort) instead of O(n²) for your previous version.
This algorithm is recording the values having the least number of occurrences so far (as it's processing) and then printing all of them alongside the value of maxCount (which is the count for the value having the overall smallest number of occurrences).
A quick fix is to record the count for each position and then only print those whose count is equal to the maxCount (which I've renamed minCount):
public static void main(String[] args) {
int[] array = { 5, 1, 2, 2, -1, 1, 5, 4 };
int[] results = new int[array.length];
int minCount = Integer.MAX_VALUE;
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array.length; j++) {
if (array[j] == array[i]) {
results[i]++;
}
}
if (results[i] <= minCount) {
minCount = results[i];
}
}
for (int i = 0; i < results.length; i++) {
if (results[i] == minCount) {
System.out.println("Element: " + i + ", Number of occurences: "
+ minCount);
}
}
}
Output:
Element: 4, Number of occurences: 1
Element: 7, Number of occurences: 1
This version is also quite a bit cleaner and removes a bunch of unnecessary variables.
This is not as elegant as Iwburks answer, but I was just playing around with a 2D array and came up with this:
public static void main(String[] args)
{
int[] array = { 3, 3, 3, 2, 2, -4, 4, 5, 4 };
int count = 0;
int maxCount = Integer.MAX_VALUE;
int[][] results = new int[array.length][];
int k = 0; // To keep index in 'results'
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array.length; j++) {
if (array[j] == array[i]) {
count++;
}
}
if (count <= maxCount) {
maxCount = count;
results[k++] = new int[]{array[i], count};
}
count = 0; // Reset 'count'
}
// Printing result
for (int h = 0; h < results.length; h++) {
if (results[h] != null && results[h][1] == maxCount ) {
System.out.println("Element: " + results[h][0] + ", Number of occurences: " + maxCount);
}
}
Prints
Element: -4, Number of occurences: 1
Element: 5, Number of occurences: 1
In your example above, it looks like you are only using ints. I would suggest the following solution in that situation. This will find the last number in the array with the least occurrences. I assume you don't want an object-oriented approach either.
int [] array = { 5, 1, 2, 40, 2, -1, 3, 2, 5, 4, 2, 40, 2, 1, 4 };
//initialize this array to store each number and a count after it so it must be at least twice the size of the original array
int [] countArray = new int [array.length * 2];
//this placeholder is used to check off integers that have been counted already
int placeholder = Integer.MAX_VALUE;
int countArrayIndex = -2;
for(int i = 0; i < array.length; i++)
{
int currentNum = array[i];
//do not process placeholders
if(currentNum == placeholder){
continue;
}
countArrayIndex = countArrayIndex + 2;
countArray[countArrayIndex] = currentNum;
int count = 1; //we know there is at least one occurence of this number
//loop through each preceding number
for(int j = i + 1; j < array.length; j++)
{
if(currentNum == array[j])
{
count = count + 1;
//we want to make sure this number will not be counted again
array[j] = placeholder;
}
}
countArray[countArrayIndex + 1] = count;
}
//In the code below, we loop through inspecting each number and it's respected count to determine which one occurred least
//We choose Integer.MAX_VALUE because it's a number that easily indicates an error
//We did not choose -1 or 0 because these could be actual numbers in the array
int minNumber = Integer.MAX_VALUE; //actual number that occurred minimum amount of times
int minCount = Integer.MAX_VALUE; //actual amount of times the number occurred
for(int i = 0; i <= countArrayIndex; i = i + 2)
{
if(countArray[i+1] <= minCount){
minNumber = countArray[i];
minCount = countArray[i+1];
}
}
System.out.println("The number that occurred least was " + minNumber + ". It occured only " + minCount + " time(s).");

Categories

Resources