I'm trying to get the minimum and maximum value of an array. The problem is that I'm not sure what exactly happens in the for loop. We create a for loop with an int. Then comes the if statement and also my question: What should numbers[i] mean? I thought that numbers already has specified size (9, by initializing { 1,2,3,...,9}). How can we change that to [i] and what does that i stand for?
public class Array {
public static void main(String[] args) {
int numbers[] = { 92, -108, 2, 120, 67, 4, -81, 9, 88, 1 };
int min, max;
min = max = numbers[0];
for (int i = 1; i < 10; i++) {
if (numbers[i] < min)
min = numbers[i];
if(numbers[i] > max){
max = numbers[i];
}
}
System.out.println("min is: " + min + "; max is: " + max);
}
}
Looking forward to your replies
numbers[i] is how you access the ith element in the array.
As Andrew Rueckert mentioned, in Java, as well as in most other major languages, array[i] notation provides access to ith element of array array. You may use square brackets [] to specify the size of an array in its definition, for example:
int[] array = new int[10];
But later on, you use brackets to specify to which element of the array you want to have access to. In your example, there is for loop iterating from 1 to 10. In each iteration it reads current (ith) element from the array numbers.
If u want get min and max value from array, you can use sort() method from java.util Arrays class.
import java.util.Arrays;
public class TestClass {
public static void main(String[] args) {
int[] numbers = { 92, -108, 2, 120, 67, 4, -81, 9, 88, 1 };
// print your array (no sorted)
System.out.println(Arrays.toString(numbers));
Arrays.sort(numbers);
//print your array (sorted)
System.out.println(Arrays.toString(numbers));
for(int i = 0; i<numbers.length;i++){
System.out.println("My array: ["+i+"] " +numbers[i]);
// min = numbers[0] = -108
// My array: [0] -108
// My array: [1] -81
// My array: [2] 1
// My array: [3] 2
// My array: [4] 4
// My array: [5] 9
// My array: [6] 67
// My array: [7] 88
// My array: [8] 92
// My array: [9] 120
// max = numbers[9] = 120
}
}
}
Lets take the barebones of what you are trying to understand
int numbers[] = { 92, -108, 2, 120, 67, 4, -81, 9, 88, 1 };
int min, max;
min = max = numbers[0];
for (int i = 1; i < 10; i++) {
if (numbers[i] < min)
min = numbers[i];
if(numbers[i] > max){
max = numbers[i];
}
}
First, you are initializing an array of numbers to whatever you have within the {}. So you have an array that is of length 10. Then we declare two int's min and max. The values are as such:
numbers[0] = 92;
numbers[1] = -108;
numbers[2] = 2;
numbers[3] = 120;
numbers[4] = 67;
numbers[5] = 4;
numbers[6] = -81;
numbers[7] = 9;
numbers[8] = 88;
numbers[9] = 1;
The next statement is declaring min and max as the very first element of the array (0 is the first, all the way up to size-1 for arrays, which in this case is 9).
min = numbers[0] (92).
max = numbers[0] (92).
Next part is the for loop, which is where all the calculations come into play. The for loop is saying start an int named i off at 1. Everytime you go through this loop, compare the boolean value in the middle, which in this case is i < 10 which means as long as i is less than 10, stay in the loop. After each iteration, do the third operation which in this case is i++, which means increment i variable by 1.
Great, we are going through the for loop. Lets start off with the first iteration, which means i is 1. We are taking the SECOND element of the numbers array (0 is the first element, remember?) and comparing that with the current value of min first (which is the first element of the array, 92).
Well if you look at the values, -108, which is the second element in the array, is less than min. Therefore, min is set to the first element in the array now. Next, we compare -108 and see if it is greater than max, which again is 92. -108 is NOT greater than 92, so it skips that if statement.
i = 1
min = numbers[1] (-108).
max = numbers[0] (92).
Lets go through the second iteration of the for loop. Since we got to the end, we do the i++ statement. Now we are at i = 2. Lets check to make sure we dont exit. Is the value of i less than 10? Yes so lets continue from the top!
Is numbers[2] (which is 2) less than the current value of min (-108)? No, skip that if statement. is numbers[2] greater than the current value of max (92)? No, lets take another look at the values:
i = 2
min = numbers[1] (-108)
max = numbers[0] (92)
Next, since we are at the bottom, do i++. i now equals 3.
This continues all the way through till i = 9, because when i = 10, it exits out of the for loop due to that middle statement in the for loop, the exit clause.
Related
I'm working on the following task.
Given an array of n integers and two integer numbers m and k.
You can add any positive integer to any element of the array such that
the total value does not exceed k.
The task is to maximize the
multiples of m in the resultant array.
Consider the following example.
Input:
n = 5, m = 2, k = 2, arr[] = [1, 2, 3, 4, 5]
Let's add 1 to the element arr[0] and 1 to arr[2] then the final array would be:
[2, 2, 4, 4, 5]
Now there are four (4) elements which are multiples of m (2).
I am not getting correct output.
My code:
public class Main {
public static void main(String[] args) {
int n = 5;
int m = 4;
int k = 3;
int count = 0;
int[] arr = {17, 8, 9, 1, 4};
for (int i = 0; i < n; i++) {
for (int j = 0; j <= k; j++) {
// check initial
if (arr[i] % m == 0) {
break;
}
// add
arr[i] = arr[i] + j;
// check again
if (arr[i] % m == 0) {
count++;
break;
}
}
}
System.out.println("Final Array : " + Arrays.toString(arr));
System.out.println("Count : " + count);
}
}
This task boils down to a well-known Dynamic programming algorithm called Knapsack problem after a couple of simple manipulations with the given array.
This approach doesn't require sorting and would be advantages when k is much smaller n.
We can address the problem in the following steps:
Iterate over the given array and count all the numbers that are already divisible by m (this number is stored in the variable count in the code below).
While iterating, for every element of the array calculate the difference between m and remainder from the division of this element by m. Which would be equal to m - currentElement % m. If the difference is smaller or equal to k (it can cave this difference) it should be added to the list (differences in the code below) and also accumulated in a variable which is meant to store the total difference (totalDiff). All the elements which produce difference that exceeds k would be omitted.
If the total difference is less than or equal to k - we are done, the return value would be equal to the number of elements divisible by m plus the size of the list of differences.
Otherwise, we need to apply the logic of the Knapsack problem to the list of differences.
The idea behind the method getBestCount() (which is an implementation Knapsack problem) boils down to generating the "2D" array (a nested array of length equal to the size of the list of differences +1, in which every inner array having the length of k+1) and populating it with maximum values that could be achieved for various states of the Knapsack.
Each element of this array would represent the maximum total number of elements which can be adjusted to make them divisible by m for the various sizes of the Knapsack, i.e. number of items available from the list of differences, and different number of k (in the range from 0 to k inclusive).
The best way to understand how the algorithm works is to draw a table on a piece of paper and fill it with numbers manually (follow the comments in the code, some intermediate variables were introduced only for the purpose of making it easier to grasp, and also see the Wiki article linked above).
For instance, if the given array is [1, 8, 3, 9, 5], k=3 and m=3. We can see 2 elements divisible by m - 3 and 9. Numbers 1, 8, 5 would give the following list of differences [2, 1, 1]. Applying the logic of the Knapsack algorithm, we should get the following table:
[0, 0, 0, 0]
[0, 0, 1, 1]
[0, 1, 1, 2]
[0, 1, 2, 2]
We are interested in the value right most column of the last row, which is 2 plus 2 (number of elements divisible by 3) would give us 4.
Note: that code provided below can dial only with positive numbers. I don't want to shift the focus from the algorithm to such minor details. If OP or reader of the post are interested in making the code capable to work with negative number as well, I'm living the task of adjusting the code for them as an exercise. Hint: only a small change in the countMultiplesOfM() required for that purpose.
That how it might be implemented:
public static int countMultiplesOfM(int[] arr, int k, int m) {
List<Integer> differences = new ArrayList<>();
int count = 0;
long totalDiff = 0; // counter for the early kill - case when `k >= totalDiff`
for (int next : arr) {
if (next % m == 0)
count++; // number is already divisible by `m` we can increment the count and from that moment we are no longer interested in it
else if (m - next % m <= k) {
differences.add(m - next % m);
totalDiff += m - next % m;
}
}
if (totalDiff <= k) { // early kill - `k` is large enough to adjust all numbers in the `differences` list
return count + differences.size();
}
return count + getBestCount(differences, k); // fire the rest logic
}
// Knapsack Algorithm implementation
public static int getBestCount(List<Integer> differences, int knapsackSize) {
int[][] tab = new int[differences.size() + 1][knapsackSize + 1];
for (int numItemAvailable = 1; numItemAvailable < tab.length; numItemAvailable++) {
int next = differences.get(numItemAvailable - 1); // next available item which we're trying to place to knapsack to Maximize the current total
for (int size = 1; size < tab[numItemAvailable].length; size++) {
int prevColMax = tab[numItemAvailable][size - 1]; // maximum result for the current size - 1 in the current row of the table
int prevRowMax = tab[numItemAvailable - 1][size]; // previous maximum result for the current knapsack's size
if (next <= size) { // if it's possible to fit the next item in the knapsack
int prevRowMaxWithRoomForNewItem = tab[numItemAvailable - 1][size - next] + 1; // maximum result from the previous row for the size = `current size - next` (i.e. the closest knapsack size which guarantees that there would be a space for the new item)
tab[numItemAvailable][size] = Math.max(prevColMax, prevRowMaxWithRoomForNewItem);
} else {
tab[numItemAvailable][size] = Math.max(prevRowMax, prevColMax); // either a value in the previous row or a value in the previous column of the current row
}
}
}
return tab[differences.size()][knapsackSize];
}
main()
public static void main(String[] args) {
System.out.println(countMultiplesOfM(new int[]{17, 8, 9, 1, 4}, 3, 4));
System.out.println(countMultiplesOfM(new int[]{1, 2, 3, 4, 5}, 2, 2));
System.out.println(countMultiplesOfM(new int[]{1, 8, 3, 9, 5}, 3, 3));
}
Output:
3 // input array [17, 8, 9, 1, 4], m = 4, k = 3
4 // input array [1, 2, 3, 4, 5], m = 2, k = 2
4 // input array [1, 8, 3, 9, 5], m = 3, k = 3
A link to Online Demo
You must change 2 line in your code :
if(arr[i]%m==0)
{
count++; // add this line
break;
}
// add
arr[i]=arr[i]+1; // change j to 1
// check again
if(arr[i]%m==0)
{
count++;
break;
}
The first is because the number itself is divisible.
and The second is because you add a number to it each time.That is wrong.
for example chenge your arr to :
int[] arr ={17,8,10,2,4};
your output is :
Final Array : [20, 8, 16, 8, 4]
and That is wrong because 16-10=6 and is bigger than k=3.
I believe the problem is that you aren't processing the values in ascending order of the amount by which to adjust.
To solve this I started by using a stream to preprocess the array. This could be done using other methods.
map the values to the amount to make each one, when added, divisible by m.
filter out those that equal to m' (already divisible by m`)
sort in ascending order.
Once that is done. Intialize max to the difference between the original array length and the processed length. This is the number already divisible by m.
As the list is iterated
check to see if k > amount needed. If so, subtract from k and increment max
otherwise break out of the loop (because of the sort, no value remaining can be less than k)
public static int maxDivisors(int m, int k, int[] arr) {
int[] need = Arrays.stream(arr).map(v -> m - v % m)
.filter(v -> v != m).sorted().toArray();
int max = arr.length - need.length;
for (int val : need) {
if (k >= val) {
k -= val;
max++;
} else {
break;
}
}
return max;
}
int m = 4;
int k = 3;
int[] arr ={17,8,9,1,4};
int count = maxDivisors(m, k, arr);
System.out.println(count);
prints
3
Here I have a Java case switch where I compare 2 randomly generated 7 number integer arrays, lottery1 array is generated earlier depending on the user input. The problem I am having is, I need to compare the two arrays and count the number of matching numbers and then print the matching numbers and how many numbers were the same.
I'm trying to put the matching numbers into the array called similar, now it's just comparing the first number of lottery1 to all of the lottery2's numbers. There's plenty of tutorials on how to compare arrays that return a bool but I need the matching numbers, please help!
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
Random rnd = new Random();
int[] lottery1 = new int[7];
for (int i = 0; i < lottery1.length; i++) {
lottery1[i] = rnd.nextInt(52);
}
Arrays.sort(lottery1);
System.out.printf("Lottery array is: %s", Arrays.toString(lottery1));
System.out.print("\nDo you want to generate an array(y/n): ");
char answer = scan.next().charAt(0);
switch (answer) {
case 'n' -> System.out.print("Goodbye!");
case 'y' -> {
int[] lottery2 = new int[7];
for (int i = 0; i < lottery2.length; i++) {
int rndNum = rnd.nextInt(52);
lottery2[i] = rndNum; //Here i fill the lottery2 with random
} numbers
Arrays.sort(lottery2);
System.out.printf("Program created an array of: %s", Arrays.toString(lottery2));
int j = 0;
int[] similar = new int[7]; //I'm trying to put the matching numbers into this new array
for (int i = 0; i < 7; i++)
{
if (lottery2[i] == lottery1[j])
{
lottery1[i] = similar[j];
i++;
j++;
}
}
System.out.printf("\nThis is how many numbers are matching: ");
System.out.printf("\nThese numbers are matching ones: ");
}
I get that you are trying to compare all numbers in 2 list and get the ones with same values I wrote this code I think it answers your question:
int[] matching = new int[7];
int[] lottery1 = new int[7];
int[] lottery2 = new int[7];
// Generate random numbers
for (int i = 0; i < 7; i++) {
lottery1[i] = (int) (Math.random() * 52.0);
lottery2[i] = (int) (Math.random() * 52.0);
}
// Compare and store matching numbers in matching array;
// The nested loop below will compare the every element of the both lists
// together and store the
// results in matching array
int matchingCount = 0;
for (int i = 0; i < 7; i++) {
for (int j = 0; j < 7; j++) {
if (lottery1[i] == lottery2[j]) {
matching[matchingCount++] = lottery1[i];
}
}
}
System.out.print("Matching Count: " + matchingCount + "\nMatch Numbers: [ ");
for (int i = 0; i < matchingCount; i++)
System.out.print(matching[i] + " ");
System.out.println("]");
int[] similar = new int[7]; //I'm trying to put the matching numbers into this new array
lottery1[i] = similar[j];
similar is an array of size 7, filled with seven 0 values (because arrays start out zeroed out). You never write anything into similar. You overwrite lottery1 with what's in similar. In other words, this code is an obtuse way to accomplish:
lottery1[i] = 0;
which surely isn't what you wanted. You also initialize similar to have size 7 but this is incorrect: Who knows how many similar numbers even exist?
You have 4 options:
Use a List<Integer> list = new ArrayList<Integer>(); - unlike arrays, arraylists don't need to be pre-sized, you can just call list.add(), and the list will take care of it. It's variable size.
Loop twice; once to determine how many matches, then you can make your similar array with the right size, and then a second time to fill it.
Make the similar array at 7, also count how many similar numbers exist, then when done copy the data over to a new array at the proper size.
Make the similar array at size 7 and use a special sentinel value (such as -1) to indicate that this one should not be shown/printed.
Also, your code is buggy: If you have replications, you overcount. Imagine lottery1 is [1,2,3,4,5,6,1] and lottery2 is [1,2,2,3,4,1,6], your algorithm would say that there are 6 matches, which doesn't sound right (the first '1' matches twice, the second '1' matches twice, and the 2 matches 2. You're going to have to think about how you want to tackle this issue.
Think about this, and write down some sample inputs + the sample output you desire, and then think about how to write code that does this. Don't just dive in.
This seems to be a good task to learn decomposition of the bigger tasks into subtasks.
The first subtask is definitely to generate an array of size K of random integer values in the given range, let's assume that for lottery the range is from 1 to N inclusive.
Then two arrays are generated, and the second subtask is to find a match between these two.
An example implementation using Stream API could be as follows:
Generate array of random integers:
static int[] getRandomArray() {
return getRandomArray(7, 52);
}
static int[] getRandomArray(int k, int n) {
int[] result = new SecureRandom().ints(1, n + 1) // n + 1 to ensure N can be included
.distinct() // make sure all elements are different
.limit(k) // pick K numbers
// .sorted() // sort the array if needed
.toArray();
System.out.println("Random array: " + Arrays.toString(result));
return result;
}
Match the results with the help of Set:
static int[] findMatch(int[] lotteryPick, int[] lotteryGuess) {
Set<Integer> set = Arrays.stream(lotteryPick).boxed().collect(Collectors.toSet());
int[] match = Arrays.stream(lotteryGuess).filter(x -> set.contains(x)).toArray();
if (match.length == 0) {
System.out.println("No matched numbers found");
} else {
String num = match.length == 1 ? " number" : " numbers";
System.out.println("Matched: " + match.length + num + ", the match: " + Arrays.toString(match));
}
System.out.println("-------------------------------");
return match;
}
Then the tests would look as simple as:
int t = 5;
while (t--> 0) {
findMatch(getRandomArray(), getRandomArray());
}
Possible output:
Random array: [26, 33, 29, 23, 49, 1, 14]
Random array: [37, 3, 27, 29, 34, 24, 36]
Matched: 1 number, the match: [29]
-------------------------------
Random array: [9, 4, 32, 27, 29, 18, 35]
Random array: [34, 2, 23, 29, 27, 6, 30]
Matched: 2 numbers, the match: [29, 27]
-------------------------------
Random array: [35, 18, 4, 42, 19, 6, 13]
Random array: [30, 8, 4, 37, 31, 9, 46]
Matched: 1 number, the match: [4]
-------------------------------
Random array: [52, 7, 47, 22, 12, 9, 26]
Random array: [46, 13, 20, 17, 1, 4, 34]
No matched numbers found
-------------------------------
Random array: [31, 40, 9, 3, 2, 49, 44]
Random array: [2, 15, 13, 36, 10, 43, 12]
Matched: 1 number, the match: [2]
-------------------------------
I'm having an issue with a method that creates an array of consecutive digits (i.e. if you input 1 and 10 as an argument, the array will include every number from 1-10), and then compares each number to another digit (e.g. 4) - if the numbers match (e.g. 4 == 4), then it removes that number from the array. Finally it returns that array.
I've implemented the method below which works sometimes, but not all the time and I'm not sure why?
For example, if I created a new array and printed each array:
ArrayList<Integer> omittedDigitArray = new ArrayList<Integer>(Omit.allIntegersWithout(20, 45, 3));
System.out.println("Array - Numbers with Omitted Digit:");
for (int n : omittedDigitArray) {
System.out.print(n + ", ");
}
The number 29 is omitted from the array? Could anyone tell me why please? Thanks!
// Creates the ArrayList
ArrayList<Integer> numberList = new ArrayList<Integer>();
// Loop creates an array of numbers starting at "from" ending at "to"
for (int i = from; i < to + 1; i++) {
numberList.add(i);
}
// Check the array to see whether number contains digit
// Code checks whether x contains 5, n == one digit
// IMPORTANT: Doesn't work on the first half of numbers i.e / will remove 3 but not 30
for (int j = 0; j < numberList.size(); j++) {
int number = (int) numberList.get(j); // This can be any integer
int thisNumber = number >= 0 ? number: -number; // if statement in case argument is negative
int thisDigit;
while (thisNumber != 0) {
thisDigit = thisNumber % 10; // Always equal to the last digit of thisNumber
thisNumber = thisNumber / 10; // Always equal to thisNumber with the last digit chopped off, or 0 if thisNumber is less than 10
if (thisDigit == omittedDigit) {
numberList.remove(j);
j--;
}
}
}
// Return the completed Array list
return numberList;
}
}
Your inner loop has a problem. Once you remove an element from the list, you should break from that loop. Otherwise you might remove unrelated additional numbers (if the omitted digit appears several times in the same number).
while (thisNumber != 0) {
thisDigit = thisNumber % 10; // Always equal to the last digit of thisNumber
thisNumber = thisNumber / 10; // Always equal to thisNumber with the last digit chopped off, or 0 if thisNumber is less than 10
if (thisDigit == omittedDigit) {
numberList.remove(j);
j--;
break; // add this
}
}
I ran your code (+ my suggested fix) with a range of 1 to 50 and omitted digit 4 and got :
[1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17, 18, 19, 20, 21, 22, 23, 25, 26, 27, 28, 29, 30, 31, 32, 33, 35, 36, 37, 38, 39, 50]
The problem in your code occurs when 44 is being processed - after you remove it (due to the first 4, you continue the while loop, find another 4 and remove another number, which happens to be 39, since the numbers 40 to 43 were already removed).
My suggested solution:
ArrayList<Integer> numberList = new ArrayList<Integer>();
// Loop creates an array of numbers starting at "from" ending at "to"
for (int i = from; i < to + 1; i++) {
numberList.add(i);
}
//removing all numbers that contain the digit
numberList.removeIf(j->containsDigit(j,thisDigit));
return numberList;
}
boolean containsDigit(int number,int thisDigit){
//making sure thisDigit is positive
thisDigit=Math.abs(thisDigit)
//if thisDigit is not a digit result is false
if(thisDigit>=10) return false;
//breaking the number into its digits
List<Integer> digits=new ArrayList<Integer>();
while(number>0){
digits.add(number%10);
number=(int) number/10;
}
return digits.contains(thisDigit);
}
I have written a (so far incomplete) method that should take an array of ints, find the difference between neighboring cells, and then return the smallest difference.
For example:
[9, 16, 4, 8, 20] --> 7, 12, 4, 12 --> 4
[12, 21, 33, 6, 3, 3] --> 9, 12, 27, 3, 0 --> 0
Here's my method:
public static int minGap(int[] a) {
int gap = 0;
for (int i = 0 ; i < (a.length - 1) ; i++) {
gap = Math.abs(a[i + 1] - a[i]);
System.out.println(gap);
}
return gap;
}
I believe that I have the intermediate step correct (finding the differences), but I cannot figure out how to then compare all them and produce the smallest one. I'm assuming I will use an if-statement, but I only have the one variable "gap" to work with.
Please let me know your suggestions.
Introduce a new variable for the smallest gap found so far. It can be initialized to something huge, probably Integer.MAX_VALUE.
In the loop, if the current gap is smaller than the smallest gap found so far, then set the smallest gap found so far to the current gap. Then after the for loop completes, you have the smallest gap.
Just add a min variable and update it as needed.
public static int minGap(int[] a) {
int gap = 0;
int min = 0;
for (int i = 0 ; i < (a.length - 1) ; i++) {
gap = Math.abs(a[i + 1] - a[i]);
if (i==0 || gap < min) min = gap;
System.out.println(gap);
}
return min;
}
Hi I want to get the lowest 3 elements of an array. By lowest I mean the minimum value. I cannot use the collections.Sort method as I need to know the index of the elements. Therefore I am using the following code to get the lowest, but I need to know how I can get the lowest 3.
int minimum = grades[1];
int index = 1;
for(i=1; i<= numberOfStudents; i++){
if (grades[i]<minimum){
minimum = grades[i];
index = i;
}
}
Here is a really simple way of doing it:
public static void main(String[] args) {
int[] myArray = { 5, 8, 12, 9, 50, 11, 4 };
System.out.println(Arrays.toString(myArray));
System.out.println(Arrays.toString(getThreeLowest(myArray)));
}
private static int[] getThreeLowest(int[] array) {
int[] lowestValues = new int[3];
Arrays.fill(lowestValues, Integer.MAX_VALUE);
for(int n : array) {
if(n < lowestValues[2]) {
lowestValues[2] = n;
Arrays.sort(lowestValues);
}
}
return lowestValues;
}
This outputs:
[5, 8, 12, 9, 50, 11, 4]
[4, 5, 8]
The call to Arrays.sort is only done to the local array, not your main array. The reason it does this is just to simplify the comparison against n.
Building off what you had
int[] grades = { 100, 99, 98, 97, 10, 95, 11, 9, 94 };
int numberOfStudents = grades.length;
int minimum = grades[1];
int minimum2 = grades[1];
int minimum3 = grades[1];
int index = 1;
int index2 = 1;
int index3 = 1;
for(int i=1; i< numberOfStudents; i++){
if (grades[i]<minimum3 && grades[i]>=minimum2){
minimum3 = grades[i];
index3 = i;
}
if (grades[i]<minimum2 && grades[i]>=minimum){
//We have a new 2nd lowest - shift previous 2nd lowest up
minimum3 = minimum2;
index3 = index2;
minimum2 = grades[i];
index2 = i;
}
if (grades[i]<minimum){
//We have a new lowest - shift previous lowest up
minimum3 = minimum2;
index3 = index2;
minimum2 = minimum;
index2 = index;
minimum = grades[i];
index = i;
}
}
System.out.println("Smallest is at " + index + " with value of " + minimum);
System.out.println("Next Smallest is at " + index2 + " with value of " + minimum2);
System.out.println("Next Smallest is at " + index3 + " with value of " + minimum3);
This may be a bit 'too much' but off the top of my head possible that you could make an array of objects, each object containing the value and index it has in the original 'grades' array and sort that?
The only other way I can think of is to good through the array and manually keep track of the 3 lowest elements and their indexes like what you're already doing...
Take three variables: the smallest, second smallest and third smallest.
In the same way you are finding your smallest element, find at each step which are the three smallest elements.
You need to check if any element is smaller than the smallest number, or it is between the smallest and the second smallest, or it is between the second smallest and the third smallest.
As this is probably an assignment, task or homework, i will not write the code here.
Can we do
int[] myArray = { 5, 8, 12, 9, 50, 11, 4 };
Arrays.sort(myArray);
System.out.println(myArray[0] +","+ myArray[1] +","+ myArray[2]);