I can find numbers<10 with if loop and store them with count++; But that is all.
I would like to see the algorithm in any lang (I can do some C++,java), so I can use it.
Go through each row and record a count of numbers less than 10.
Store that aside, go to next row, do same thing, compare, throw out lower one.
public int findMostLowNumbersRow(double[][] arr, double threshold) {
int maxLowNumbers = 0;
int rowNum = -1;
for (int i = 0; i < arr.length; ++i) {
int count = countLowNumbers(arr[i], threshold);
if (count > maxLowNumbers) {
rowNum = i;
maxLowNumbers = count;
}
}
return rowNum;
}
public int countLowNumbers(double[] row, double threshold) {
int count = 0;
for (double number : row) {
if (number < threshold) {
++count;
}
}
return count;
}
call with
findMostLowNumbersRow(yourMatrix, 10.0);
the function returns the number of the row that contains the most numbers less than 10.
int max_count = 0;
for (int i=0; i<MATRIX_SIZE; i++) {
int tmp_count = 0;
for (int j=0; j<MATRIX_SIZE; j++) {
if (matrix[i][j] > 10) tmp_count++;
}
if (tmp_count > max_count) max_count = tmp_count;
}
// use max_count
It's something like the following:
import static java.lang.System.out;
public class Zeug {
public static void main(String[] args) {
final int SIZE = 10;
int[][] matrix = new int[SIZE][SIZE];
for(int i=0;i<matrix.length;i++) {
for(int j=0;j<matrix.length;j++) {
matrix[i][j] = (int) Math.round(Math.random() * 23);
}
}
int max=0;
for(int i=0;i<matrix.length;i++) {
int count=0;
for(int j=0;j<matrix.length;j++) {
if(matrix[i][j]<10) {
count++;
}
}
max = Math.max(count, max);
}
out.println(max);
}
}
Write some pseudo-code and it'll be clearer:
Set the index of the lowest row equal to the first one.
Set the max count of values below the threshold to zero.
Loop over all rows.
Set the count of values below the threshold to zero.
Loop over all the columns in the current row and count the number of values below the threshold.
If the count of values below the current threshold is greater than the max count, set the index of the lowest row equal to the current one.
You'll need two nested loops and some counters.
Since you said any language, here we go in Ruby
matrix.max { |a,b| a.select{|e|e<10}.size <=> b.select{|e|e<10}.size }
assuming that matrix is an array of arrays.
Related
I am trying to display the current row that has the max value. So far I have the max value by adding the elements in the array but I am trying to display the specific row it is in. For example:
{4,4,4}
{5,5,5}
:25 is the biggest val possible going by row to row
The max value here would be 15 as my code looks and finds the maximum addition in each row in a 2D array. How would I get my code to display the row {5,5,5} as well as the actual maximum addition that is possible with the given rows.
Here is my current code:
public class review{
int largestRowsSum(int[][] arr){
int sum = 0;
int largest = 0;
for (int i = 0; i < arr.length; i++){
for(int j = 0; j < arr[i].length; j++){
sum += arr[i][j];
}
if(sum > largest){
largest = sum;
}
sum = 0;
}
return largest;
}
}
First, your current method could be simplified and static. Like,
static int largestRowsSum(int[][] arr) {
int sum = Arrays.stream(arr[0]).sum();
for (int i = 1; i < arr.length; i++) {
sum = Math.max(Arrays.stream(arr[i]).sum(), sum);
}
return sum;
}
Second, you could invoke that method and then iterate the array to find the index of the array with the matching sum. Like,
static int largestRowIndex(int[][] arr) {
int target = largestRowsSum(arr);
for (int i = 0; i < arr.length; i++) {
if (Arrays.stream(arr[i]).sum() == target) {
return i;
}
}
return -1;
}
Finally, call that method and use the returned index to display the row and correct sum. Like,
public static void main(String[] args) {
int[][] arr = { { 4, 4, 4 }, { 5, 5, 5 } };
int n = largestRowIndex(arr);
System.out.printf("The largest row is %s and the sum is %d.%n",
Arrays.toString(arr[n]), Arrays.stream(arr[n]).sum());
}
Outputs, the row {5,5,5} as well as the actual maximum, as requested
The largest row is [5, 5, 5] and the sum is 15.
The output of this program works fine. But there's one thing I've not been able to implement. In some cases, I don't have a row or column with the highest number of 1s. Sometimes I have 2 or more rows/columns which have the same "HIGHEST" number of ones. But my program only returns 1 row/column.
I want a case whereby If i have more than 2 rows/columns with the same highest number of 1s. Both rows will be displayed. e.g. "Row(s) with the most 1's: 1,2" or if it's a column it can say "Row(s) with the most 1's: 1,2".
Please I need help with this. I'm stuck.
import java.util.Random;
import java.util.Scanner;
public class LargestRowColumn
{
// declare a 2 dimensional array or an array of arrays
private static int[][] randArray;
public static void main(String[] args)
{
do
{
// Create a scanner to get Input from user.
Scanner scanner = new Scanner(System.in);
System.out.print("\nEnter the array size n:");
int rows = scanner.nextInt();
int cols = rows;
randArray = new int[rows][cols];
// loop through the number of rows in thw array
for (int i = 0; i < randArray.length; i++)
{
// loop through the elements of the first array in the array
for (int j = 0; j < randArray[0].length; j++)
{
// set a random int 0-1 to the array
randArray[i][j] = getRandomInt(0, 1);
// print the number just assigned
System.out.print(randArray[i][j]);
}
// make a linebreak each row.
System.out.println();
}
System.out.print("Row(s) with the most 1's: " + scanRow(randArray) + "\n");
System.out.print("Columns(s) with the most 1's: " + scanColumn(randArray) + "\n");
}
while(true);
}
// quick method I made to get a random int with a min and max
public static int getRandomInt(int min, int max)
{
Random rand = new Random();
return rand.nextInt(max-min+1)+min;
}
public static int scanRow(int[][] array)
{
int result = -1;
int highest = -1;
for (int row = 0; row < array.length; row++)// Here we are about start looping through the matrix values
{
int temp = 0; // Setting the first index to 0.
for (int col = 0; col < array[row].length; col++)//
{
//Assign current location to temporary variable
temp = temp + array[row][col];
}
if (temp > highest)
{
highest = temp;
result = row + 1;
}
}
return result;
} // end of row method
private static int scanColumn(int[][] array)
{
int result = -1;
int highest = -1;
// declare and initialize the variable(here you've 'created' it, to then call it on if statement)
int col = 0;
for (int row = 0; row < array.length; row++)
{
int temp = 0;
//declare the variable in the for loop
for (col = 0; col < array[row].length; col++)
{
//Assign current location to temp variable
temp = temp + array[row][col];
}
if (temp > highest)
{
highest = temp;
result = col;
}
}
return result;
}
}
I would suggest a different approach, first thing why do you need to loop all over the 2D array again , u can figure out the highest 1's in rows and columns while inserting them and insert them in an array ( array of rows and array for columns) the carry will be of custom type which is a class with two parameters , score(which is number of 1's) and index( which is the number of the row or column), then sort the arrays and print the indexes related to top scores.
if you are expecting to receive the array with the inputs you can do the same but with new loop.
so your insert loop will be like this
List<Wrapper> rowsList = new ArrayList<Wrapper>(rows);
List<Wrapper> colsList = new ArrayList<Wrapper>(cols);
for(int i=0;i<cols;i++) {
colsList.add(new Wrapper(i,0));
}
// loop through the number of rows in thw array
for (int i = 0; i < rows; i++)
{
int sum =0;
// loop through the elements of the first array in the array
for (int j = 0; j < cols j++)
{
// set a random int 0-1 to the array
randArray[i][j] = getRandomInt(0, 1);
// print the number just assigned
System.out.print(randArray[i][j]);
sum+=randArray[i][j];//add for row
colsList.get(j).setScore(colsList(j).getScore() +randArray[i][j]);//add for column
}
rowsList.add(new Wrapper(i,sum));
// make a linebreak each row.
}
Collections.sort(rowsList,new Comparator<Wrapper>() {
#Override
public int compare(Wrapper obj1,Wrapper obj2) {
if(obj1.getScore() > obj2.getScore())
return -1;
if(obj1.getScore() < obj2.getScore())
return 1;
return 0;
}
});
if(rowsList.isEmpty())
return -1;
int max = rowsList.get(0).getScore();
for(Wrapper obj:rowsList) {
if(obj.getScore()< max)
break;
System.out.println(obj.getIndex);
}
//DO THE SAME FOR COLUMNS
your wrapper class will be
public class Wrapper {
private int index;
private int score;
public Wrapper(int index,int score) {
this.index = index;
this.score = score;
}
public int getIndex() {
return this.index;
}
public int getScore() {
return this.score;
}
public void setScore(int score) {
this.score = score
}
}
This is in keeping with the OP use of arrays.
Instead of returning an int, which would be one row, you can return int[].
Personally, I would init the int[] to the number of rows in the array, because what if every row has the same number of 1's?
int[] results = new int[array[0].length];
Then, instead of adding in the rows, I would have a variable used to designate which spot to add the row to, i.e., results[0] etc.
int index = 0;
Then, all it takes is a small adjustment to how you add your results to the array.
public static int[] scanRow(int[][] array)
{
int highest = -1;
int index = 0; //ADD HERE
int[] results = new int[array[0].length]; //ADD HERE
... //Your code here
if (temp > highest)
{
highest = temp;
//CLEAR THE RESULT LIST
for(int x = 0; x < results.length; x++){
results[x] = -1;
}
index = 0; //RESET THE INDEX
results[index] = row + 1;
index ++;
} else if (temp == highest{
highest = temp;
results[index] = row + 1;
index ++;
}
}
return results;
} // end of row method
Personally, I would use an ArrayList for these types of things, so heres how I would do it using it.
I would make the return type of the method an ArrayList<int>.
public static ArrayList<int> scanRow(int[][] array)
Then declare my ArrayList<int>
ArrayList<int> results = new ArrayList<>();
and the if statements are a little easier to handle, since ArrayList as a clear() and add() method.
if (temp > highest)
{
highest = temp;
//CLEAR THE RESULT LIST
results.clear();
results.add(row+1);
} else if (temp == highest{
highest = temp;
results.add(row + 1);
}
EDIT
Don't forget to edit your print statements accordingly.
I am defining a function to accept a matrix (2d array), for example x[][]; and the function should print the biggest even number in each line
public static void biggestEvenNumOfEachLine(int x[][]){
int even,t=0,max;
int arr[] = new int [x.length];
for(int i = 0; i < x.length;i++){
for(int j = 0; j < x[i].length;j++,t++){
if(x[i][j] % 2 == 0){
even = x[i][j];
arr[j] = even;
}
}
}
}
What am I missing?
I would start by finding the biggest even number in a single line array. Start with the smallest possible value, and then iterate the array. Test for even, and then set the max (and then return it). Something like,
private static int biggestEvenNum(int[] x) {
int max = Integer.MIN_VALUE;
for (int i = 0; i < x.length; i++) {
if (x[i] % 2 == 0) {
max = Math.max(max, x[i]);
}
}
return max;
}
But, in Java 8+, I would prefer to filter for even values and get the max like
private static int biggestEvenNum(int[] x) {
return IntStream.of(x).filter(v -> v % 2 == 0).max().getAsInt();
}
Then your method is as simple as iterating the line(s) in your matrix, printing the result. Like,
public static void biggestEvenNumOfEachLine(int[][] x) {
for (int[] line : x) {
System.out.println(biggestEvenNum(line));
}
}
public static void biggestEvenNumOfEachLine(int x[][])
{
int arr[] = new int [x.length];
for(int i = 0; i < x.length;i++)
for(int j = 0; j < x[i].length;j++)
if(x[i][j] % 2 == 0 && x[i][j] > arr[i]){
arr[i] = x[i][j];
System.out.println(arr[i]);
}
}
This will work but if there is no even number at particular line then corresponding number to that line will be zero.
I was wondering how to get the mode of a 2d array in java. What are some different ways I could approach the problem? So far here is my code for the method. EDIT: Also, i forgot to mention that the array has to be positive and single digit numbers so numbers from 0-9 inclusive.
public static int getMostRepeatedNumber(int[][] array) {
int theMode = 0;
if(array.length < 0){
return -1;
}
for(int row = 0; row <array.length;row++){
for(int col = 0; col <array[0].length; col++){
int temp = array[row][col];
}
}
return theMode;
}
Because elements in array are all single digit (from 0 to 9), so we can count and store the frequency of each value easily using an array int[]freq with length 10.
int[]freq = new int[10];
for(int[] row : array){
for(int val : row)
freq[val]++;
}
int mode = 0;
for(int i = 1; i < 10; i++)
if(freq[i] > freq[mode])
mode = i;
return mode;
Since you are only dealing with integers from 0 through 9, the easiest approach is to build a frequency table and then scan for the largest value:
public static int getMostRepeatedNumber(int[][] array) {
if(array == null){
return -1;
}
// build frequency table
int[] frequencies = new int[10]; // all zero
for(int [] row : array){
for(int val : row){
frequencies[val]++;
}
}
// scan for the largest value
int largest = 0;
int mode = -1;
for (int i = 0; i < 10; ++i) {
if (frequencies[i] > largest) {
largest = frequencies[i];
mode = i;
}
}
return mode;
}
So I created an array with random numbers, i printed and counted the repeated numbers, now I just have to create a new array with the same numbers from the first array but without any repetitions. Can't use ArrayList by the way.
What I have is.
public static void main(String[] args) {
Random generator = new Random();
int aR[]= new int[20];
for(int i=0;i<aR.length;i++){
int number=generator.nextInt(51);
aR[i]=number;
System.out.print(aR[i]+" ");
}
System.out.println();
System.out.println();
int countRep=0;
for(int i=0;i<aR.length;i++){
for(int j=i+1;j<aR.length-1;j++){
if(aR[i]==aR[j]){
countRep++;
System.out.println(aR[i]+" "+aR[j]);
break;
}
}
}
System.out.println();
System.out.println("Repeated numbers: "+countRep);
int newaR[]= new int[aR.length - countRep];
}
Can someone help?
EDIT: Can't really use HashSet either. Also the new array needs to have the correct size.
Using Java 8 and streams you can do the following:
int[] array = new int[1024];
//fill array
int[] arrayWithoutDuplicates = Arrays.stream(array)
.distinct()
.toArray();
This will:
Turn your int[] into an IntStream.
Filter out all duplicates, so retaining distinct elements.
Save it in a new array of type int[].
Try:
Set<Integer> insertedNumbers = new HashSet<>(newaR.length);
int index = 0;
for(int i = 0 ; i < aR.length ; ++i) {
if(!insertedNumbers.contains(aR[i])) {
newaR[index++] = aR[i];
}
insertedNumbers.add(aR[i]);
}
One possible approach is to walk through the array, and for each value, compute the index at which it again occurs in the array (which is -1 if the number does not occur again). The number of values which do not occur again is the number of unique values. Then collect all values from the array for which the corresponding index is -1.
import java.util.Arrays;
import java.util.Random;
public class UniqueIntTest
{
public static void main(String[] args)
{
int array[] = createRandomArray(20, 0, 51);
System.out.println("Array " + Arrays.toString(array));
int result[] = computeUnique(array);
System.out.println("Result " + Arrays.toString(result));
}
private static int[] createRandomArray(int size, int min, int max)
{
Random random = new Random(1);
int array[] = new int[size];
for (int i = 0; i < size; i++)
{
array[i] = min + random.nextInt(max - min);
}
return array;
}
private static int[] computeUnique(int array[])
{
int indices[] = new int[array.length];
int unique = computeIndices(array, indices);
int result[] = new int[unique];
int index = 0;
for (int i = 0; i < array.length; i++)
{
if (indices[i] == -1)
{
result[index] = array[i];
index++;
}
}
return result;
}
private static int computeIndices(int array[], int indices[])
{
int unique = 0;
for (int i = 0; i < array.length; i++)
{
int value = array[i];
int index = indexOf(array, value, i + 1);
if (index == -1)
{
unique++;
}
indices[i] = index;
}
return unique;
}
private static int indexOf(int array[], int value, int offset)
{
for (int i = offset; i < array.length; i++)
{
if (array[i] == value)
{
return i;
}
}
return -1;
}
}
This sounds like a homework question, and if it is, the technique that you should pick up on is to sort the array first.
Once the array is sorted, duplicate entries will be adjacent to each other, so they are trivial to find:
int[] numbers = //obtain this however you normally would
java.util.Arrays.sort(numbers);
//find out how big the array is
int sizeWithoutDuplicates = 1; //there will be at least one entry
int lastValue = numbers[0];
//a number in the array is unique (or a first duplicate)
//if it's not equal to the number before it
for(int i = 1; i < numbers.length; i++) {
if (numbers[i] != lastValue) {
lastValue = i;
sizeWithoutDuplicates++;
}
}
//now we know how many results we have, and we can allocate the result array
int[] result = new int[sizeWithoutDuplicates];
//fill the result array
int positionInResult = 1; //there will be at least one entry
result[0] = numbers[0];
lastValue = numbers[0];
for(int i = 1; i < numbers.length; i++) {
if (numbers[i] != lastValue) {
lastValue = i;
result[positionInResult] = i;
positionInResult++;
}
}
//result contains the unique numbers
Not being able to use a list means that we have to figure out how big the array is going to be in a separate pass — if we could use an ArrayList to collect the results we would have only needed a single loop through the array of numbers.
This approach is faster (O(n log n) vs O (n^2)) than a doubly-nested loop through the array to find duplicates. Using a HashSet would be faster still, at O(n).