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.
Related
I am pretty new to java and am just learning 2D arrays. I need to get the top 5 numbers and have tried everything I could think of. I was able to get the highest number using an If statement but am not able to get past that. I figured that I would try and get the second number and then move on to the rest. My friend said he got it done using for loops but I also could not get that to work. Any help would be appreciated. Thanks!
This is the code that I used:
package secondAssignment;
import java.util.Random;
public class BiggestNumbersRectangular {
public static void main(String[] args) {
Random rand = new Random();
int[][] arrSize = new int [4][5];
for (int i = 0; i < arrSize.length; i++) {
for (int j=0; j< arrSize.length; j++) {
arrSize[i][j] = rand.nextInt(89) + 10;
System.out.print(arrSize[i][j] + " ");
}
System.out.println();
}
int max = arrSize [0][0];
int largeNumTwo = arrSize [0][0];
for (int i = 0; i < arrSize.length; i++) {
for (int j = 0; j < arrSize.length; j++) {
if (max < arrSize[i][j]) {
max = arrSize [i][j];
if (largeNumTwo < max) {
arrSize [i][j] = largeNumTwo;
}
}
}
}
System.out.println("Highest Number: " + max);
System.out.println("Second Highest Number:" + largeNumTwo);
}
}
The output that I get is this:
45 10 44 70
36 87 35 38
68 14 30 79
34 69 50 92
Highest Number: 92
Second Highest Number:45
The code that I used for the second number is outputting only the first randomly generated number.
I am not sure how to fix this.
If you're allowed to use a List, then I'd do it this way.
There's nothing terribly fancy in here:
import java.util.*;
class Main {
public static void main(String[] args) {
Random rand = new Random();
int[][] arrSize = new int [4][5];
for (int row = 0; row < arrSize.length; row++) {
for (int col=0; col < arrSize[row].length; col++) {
arrSize[row][col] = rand.nextInt(89) + 10;
}
}
displayArray(arrSize);
List<Integer> top5 = new ArrayList();
for (int row = 0; row < arrSize.length; row++) {
for (int col=0; col < arrSize[row].length; col++) {
int current = arrSize[row][col];
// see if current is larger than anything in top5
boolean added = false;
for(int i=0; i<top5.size() && !added; i++) {
if (current >= top5.get(i)) {
// insert new top 5 number in correct spot
top5.add(i, current);
added = true;
}
}
if (!added && top5.size() < 5) {
top5.add(current); // add it to the end
}
else if (added && top5.size() > 5) {
top5.remove(top5.size() - 1); // remove 6th largest
}
}
}
// display the top 5 numbers from the 2D array
for(int i=0; i<top5.size(); i++) {
System.out.println("#" + (i+1) + ": " + top5.get(i));
}
}
public static void displayArray(int[][] numbers) {
for(int[] row : numbers) {
System.out.println(Arrays.toString(row));
}
}
}
Sample run:
[38, 63, 19, 17, 11]
[49, 42, 98, 71, 32]
[54, 74, 89, 44, 56]
[56, 91, 52, 72, 49]
#1: 98
#2: 91
#3: 89
#4: 74
#5: 72
This is basically the same approach that Javohir Xoldorov took, but the code is a little easier to understand because we can easily add, insert, and delete elements from a List without having to manually shift everything like you would in an Array.
Maybe you can see this solution.
Approach:
you can declare five variable but then You will use most if so we can:
Declare static array size = 5
Fill array which possible min val INT_MIN
We get one element given matrix and compare five element If which element < firstArray[i] then it changed and before matrix element one step move right side
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
Random rand = new Random();
int[][] arr = new int[4][5];
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr.length; j++) {
arr[i][j] = rand.nextInt(89) + 10;
System.out.print(arr[i][j] + " ");
}
System.out.println();
}
int[] max_element = new int[5];
for (int i = 0; i < max_element.length; i++) {
max_element[i] = Integer.MIN_VALUE;
}
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
for (int k = 0; k < max_element.length; k++) {
if (max_element[k] < arr[i][j]) {
int before = max_element[k], current;
for (int z = k + 1; z < max_element.length; z++) {
current = max_element[z];
max_element[z] = before;
before = current;
}
max_element[k] = arr[i][j];
break;
}
}
}
}
for (int i = 0; i < max_element.length; i++) {
System.out.println((i + 1) + " Highest Number: " + max_element[i]);
}
}
}
UPDATE 2: After testing, I changed my algorithm now finally to work really correctly if the highest value of all is contained within the first five entries. And I produced code:
package examples.stackoverflow.q75461466;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
public class Q75461466 {
public static void main(String[] args) {
int[][] myArray = initRandomArray(4, 5, 79, 10);
// for testing it's better to work with a fixed dataset
// int[][] myArray = {{94, 61, 17, 27, 67}, {68, 74, 46, 61, 98}, {42, 79, 95, 77, 39}, {41, 42, 97, 50, 76}};
System.out.print("Original data: ");
System.out.println(Arrays.deepToString(myArray));
List<Integer> topFive = new ArrayList<>();
Integer min = Integer.MIN_VALUE;
for (int[] row : myArray) {
for (int value : row) {
if ((value > min) || topFive.size() < 5) {
topFive.add(value);
if (topFive.size() > 5) {
topFive.remove(min);
}
min = topFive.stream().min(Integer::compareTo).orElse(Integer.MIN_VALUE);
}
}
}
System.out.print("The 5 highest numbers are: ");
System.out.println(topFive);
}
private static int[][] initRandomArray(int height, int width, int upper, int lower) {
int[][] randomArray = new int[height][width];
Random rand = new Random();
for (int row = 0; row < randomArray.length; row++) {
for (int col = 0; col < randomArray[row].length; col++) {
randomArray[row][col] = rand.nextInt(upper + lower) + lower;
}
}
return randomArray;
}
}
First the array is initialized and filled with data in the method initRandomArray. Please note that for testing it is better if you work with a fixed array, it will get you reproducible results where you also can simulate "problematic" cases.
Then the list topFive is used - a name a bit misleading, because it does not contain five elements all the time.
I loop over all the entries in the arrays with two nested loops (the code is written to be independent of the actual array dimensions, otherwise further optimizations could have been done).
Array indexes are not necessary, the for-each variant is sufficient, as I only need each value once.
I make sure that the first five entries are always put into the topFive list, and I always track the minimum value inside that list (in min). For this I use a bit "stream magic", the orElse(Integer.MIN_VALUE) in the end is needed since the min method returns an Optional in the case the list is empty. Should never happen in this algorithm, but the Optional has to be handled properly.
After five values are in the list, it is relevant if the next input value is bigger than the smallest value already in the list - if so, then the input value is added to the list, and the current minimum value is removed.
The new minimum value has to be calculated, as the value just inserted is not necessarily the new minimum.
After all values of the arrays have been processed, the list contains five values at maximum, so it can be directly output as the result.
The resulting list will not be sorted, but will contain the values in the order of their first occurrence.
In the case that the first five input values contain a value more than once, it is possible that the output list contains the same value also more than once.
I'd suggest doing this using Java's PriorityQueue class. While it might be overkill for 5 items, it's quite straightforward to use and will perform extremely well for larger target sets.
The default constructor gives a min priority queue, which is exactly what we want. Add the first desiredQty items to the priority queue. The minimum of those will be at the front of the queue, and can be inspected using peek(). For all subsequent values in the array, compare them to the current minimum value. If the new value is larger than the current minimum, toss the min and add the current value. When you get to the end of the array the priority queue will contain the desiredQty largest values, so you can just iterate through and print them (or do whatever else suits your fancy).
import java.util.Arrays;
import java.util.Random;
import java.util.PriorityQueue;
class Top5 {
public static void main(String[] args) {
Random rand = new Random();
PriorityQueue<Integer> pq = new PriorityQueue<Integer>();
int[][] arr = new int [4][5];
int desiredQty = 5;
for (int row = 0; row < arr.length; row++) {
for (int col=0; col < arr[row].length; col++) {
arr[row][col] = rand.nextInt(89) + 10;
if (pq.size() < desiredQty) {
// If we don't yet have desiredQty items, just add the latest one to pq.
pq.add(arr[row][col]);
} else {
// If pq has the desiredQty and the latest value is bigger than
// the current min, remove the min and add the latest value.
if (arr[row][col] > pq.peek()) {
pq.poll();
pq.add(arr[row][col]);
}
}
}
System.out.println(Arrays.toString(arr[row]));
}
System.out.println("\n" + desiredQty + " largest values are:");
System.out.println(Arrays.toString(pq.toArray()));
}
}
Sample output:
[55, 82, 92, 93, 79]
[84, 26, 78, 87, 23]
[49, 67, 76, 37, 18]
[12, 39, 54, 38, 68]
5 largest values are:
[82, 84, 92, 93, 87]
I am trying to create a 3x3 matrix that has the numbers 1 to 9 generated at different locations each time you run the code. the method I came up with does not work and I can't find out why it doesn't work, so if anyone could point out the reason why it does not work it would be really really appreciated.
and if anyone knows how to solve this problem in any other way please let me know.
Here's the method I created:
public static int[][] randgen() {
Random rand = new Random();
int[][] a = new int[3][3];
int x;
for(int i = 0; i<a.length; i++) {
for (int j = 0; j < a.length; j++) {
a[i][j] = rand.nextInt(8) +1;
do {
x = 1;
for(int k = 0; k<i; k++) {
for(int l = 0; l<j; l++) {
if(a[k][l] == a[i][j]) {
x++;
}
}
}
if(x!=1) {
a[i][j] = rand.nextInt(8) +1;
}
} while (x!=1); //this while loop I'm using as a way to find duplicates and keep changing up the number until I reach an integer with no duplicates, and this is the part of the program that is failing and I can't understand why
}
}
}
I've tried creating a sorted algorithm and then making a function to shuffle some of the elements which also did not work.
The only thing that worked for me is creating an ArrayList and then printing it out in a way that it looks like an array
Another variation...
Populate the list with the numbers 1 to 9 but then pick a random spot from it to fill the next slot of your array. Each time you pick a random spot from the list you remove it.
Might look like:
import java.util.List;
import java.util.ArrayList;
import java.util.Random;
import java.util.Arrays;
class Main {
public static void main(String[] args) {
Random rand = new Random();
int[][] a = new int[3][3];
int counter = 1;
int totalSpots = a.length * a[0].length; // assumes RECTANGULAR array
List<Integer> numbers = new ArrayList<Integer>();
while (counter <= totalSpots) {
numbers.add(counter);
counter++;
}
for(int row = 0;row < a.length; row++) {
for(int col = 0; col < a[0].length; col++) {
int index = rand.nextInt(numbers.size());
a[row][col] = numbers.get(index);
numbers.remove(index);
}
}
for(int[] row : a) {
System.out.println(Arrays.toString(row));
}
}
}
Sample output:
[5, 3, 6]
[9, 4, 8]
[2, 7, 1]
If we change the size of the array:
int[][] a = new int[5][4];
It sill works:
[7, 3, 6, 11]
[19, 20, 1, 4]
[13, 12, 17, 2]
[5, 18, 9, 16]
[14, 15, 10, 8]
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);
}
i am trying to solve some basic java question:
i have an array like int[] x = { 12, 24, 33 };. I need to break it into digits like {1, 2, 2, 4, 3 ,3} and then count the repeating numbers this way: 1:1, 2:2, 3:2, 4:1.
Until now i got this code but i can't save the digits into array.
Can some one help me ?
public class targil_2_3 {
public static void main(String[] args) {
int[] x = { 12, 24, 33 };
int[] ara = new int[x.length * 2];
for (int i = 0; i < x.length; i++) {
for (int j = 0; j < 2; j++) {
ara[j] = x[i] % 10;
x[i] = x[i] / 10;
System.out.println(ara[j]);
}
}
}
}
You dont need to store individual digits, you need to store just count for digits. Lets assume, that you're working with 10 based numbers, then code can looks like
public static void main(String[] args) {
int[] x = { 12, 24, 33, 0, 10, 555 };
int[] count = new int[10];
for (int i = 0; i < x.length; i++) {
int num = x[i];
if (num == 0) {
count[0]++;
continue;
}
while (num > 0) {
count[num % 10]++;
num = num / 10;
}
}
System.out.println(Arrays.toString(count));
}
Output is
[2, 2, 2, 2, 1, 3, 0, 0, 0, 0]
import java.util.Arrays;
import java.util.Map;
import static java.util.stream.Collectors.*;
public class Use {
public static void main(String[] args) {
int[] x = { 12, 24, 33 };
Map<Integer, Long> result = Arrays.stream(x).boxed()
.map(String::valueOf)
.collect(joining())
.chars().boxed()
.collect(groupingBy(Character::getNumericValue, counting()));
System.out.println(result); //prints {1=1, 2=2, 3=2, 4=1}
}
}
Explanation
First line convert an int[] to a Stream<Integer> (for each element)
Convert Stream<Integer> to Stream<String>
Reduce the Stream<String> to String
Create a Stream<Integer> (for each digit)
Count the occurences of each digit in a Map
we have only 10 decimal digits from 0 to 9 , [0..9]
so we make an array with length 10 , like count :
int count[] = new int[10];
for(int i = 0 ; i < x.length ; i++){
if( x[i] == 0 ){
count[0]++;
continue;
}
while(x[i]!=0){
int index = x[i] % 10;
count[index]++;
x[i] /= 10;
}
}
then we will have the number of digits in count array , so we can print it :
for(int i = 0 ; i < 10 ; i++)
System.out.println(i+" : "+count[i]);
if your data is so big it is better to use Map
there are many ways to do this
Digits are 0-9. Build a counter array of size 10, and count each digit extracted in the proper index of the counter array ("counter[digit]++").
Edit: Of- course, in the end you can build the desired result array based on the counter array.
For example: result[0] = "0:" + counter[0];"
Good Luck!
I wrote the following code to get all of the numbers from 0 to 1000 that are multiples of three:
public class Hi {
public static void main(String[] args) {
for(int i = 0; i<1000; i++)
if(i % 3 == 0)
System.out.println(i);
}
}
Now I would like to add these numbers together and print the result after the loop.
No need to test for multiplicity of 3 if you iterate by multiples of 3. Finally, to add numbers you should be performing arithmetic. Something like,
long sum = 0;
for (int i = 3; i < 1000; i += 3) {
sum += i;
}
System.out.println(sum);
Or, in Java 8+, using an IntStream (for the same result) like
System.out.println(IntStream.rangeClosed(1, 1000 / 3).map(i -> i * 3).sum());
....And because we all will need java-8 and lambdas oneday...
final List<Integer> myList = new ArrayList<>(Arrays.asList(new Integer[]{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 4, 2, 2 }));
final int sum = myList.stream().filter((i) -> i.intValue() % 3 == 0).mapToInt(Integer::intValue).sum();
System.out.println("Sum of divisible by 3 is " + sum);
As you go through the numbers from 1 to 1000, you can add the multiple of 3 to a list. Then, you could go through that list, and add each number in that list to a sum.
public class Hi {
public static void main(String[] args) {
int[] multiples = new int[1000]; // default initialized with zeroes
mIndex = 0;
for(int i = 0; i<1000; i++) {
if(i % 3 == 0) {
System.out.println(i);
multiples[mIndex] = i;
mIndex++;
}
}
int sum2 = 0;
for(int i2 = 0; i2<mIndex; i2++)
sum2 += multiples[i2];
System.out.println(sum2);
}
}
But that involves going through the numbers twice, and creating another list. It's simpler and more efficient to add the multiple of 3 to a sum as you go from 1 to 1000.
public class Hi {
public static void main(String[] args) {
int sum = 0;
for(int i = 0; i<1000; i++)
if(i % 3 == 0) sum += i;
System.out.println(sum);
}
}
Edit: As the other poster said, there are smarter ways to do this. There are also math formulas for getting this sum in O(1).