Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
. Basically what the following code does (suppose to) is, create a set of non-repeating random numbers, fill them up to an array which gets converted to a list, and sort them out. The problem is the nested for loops, i managed a work around but not even sure how it works. Secondely, i cant seem to sort it correctly, things repeat and out of bound errors pop up from time to time.
How the code works:
Generate non-repeating random numbers
Fill an array with them
Use nested for loop to find the smallest value
Insert that to a new array
Remove it from the first array
Repeat last 2 steps till the first array is empty and second array
os filled in a sorted order
import org.apache.commons.lang.ArrayUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.*;
import java.lang.*;
import java.io.*;
public class Sorter {
public static void main(String[] args) {
int[] process = fillArray(20,1,25);
sorter(process,20);
}
public static int[] sorter(int array[],int size) {
int[] useArray = array;
Integer[] newArray = ArrayUtils.toObject(useArray);
List<Integer> arrayList = new ArrayList(Arrays.asList(newArray));
//System.out.println((arrayList));
int counter = 1;
int minval = 0;
int diffsize = size - 1;
int actualVal = 0;
int storeArray[] = new int[size];
int removeIndex =0;
Integer[] newStore = ArrayUtils.toObject(storeArray);
List<Integer> storeList = new ArrayList(Arrays.asList(newStore));
System.out.println((arrayList));
// Both loops messed up
for (int i = 0; i < size+diffsize; i++) {
for (int n = 0; n < size-1; n++) {
if (arrayList.get(minval) < arrayList.get(counter)) {
actualVal = arrayList.get(minval);
System.out.println((arrayList.get(minval)) + " Less than " + arrayList.get(counter));
counter = counter + 1;
removeIndex = minval;
} else {
actualVal = arrayList.get(counter);
System.out.println((arrayList.get(counter)) + " Less than " + arrayList.get(minval));
minval = counter;
counter = counter + 1;
removeIndex = counter;
}
}
// System.out.println(actualVal);
storeList.add(actualVal);
arrayList.remove(actualVal); // need to remove the smallest value to repeat the sorting and get the next smallest value, but this is not removing it
size = size - 1;
counter = 1;
minval = 0;
// if (i + size == i) {
// storeList.set(i, arrayList.get(0));
// }
// System.out.println(removeIndex);
// System.out.println(arrayList);
}
// System.out.println(storeList);
int[] ints = new int[storeList.size()];
int d = 0;
for (Integer u : storeList) {
ints[d++] = u;
}
return ints;
}
public static int randomNum(int lower,int upper){
Random rand = new Random();
int randomNum = lower + rand.nextInt((upper- lower) + 1);
return randomNum;
}
public static int[] fillArray(int size,int lowerBound,int upperBound){
int holdArray[] = new int[size];
int rand = 0;
for (int count =0;count < holdArray.length;count++){
holdArray[count] = 0;
}
for (int count =0;count < holdArray.length;count++){
rand = randomNum(lowerBound,upperBound);
if (ArrayUtils.contains(holdArray, rand)) {
while (ArrayUtils.contains(holdArray, rand)) {
rand = randomNum(0, 20);
}
}
holdArray[count] = rand;
}
// System.out.println(Arrays.toString(holdArray));
//return holdArray;
return holdArray;
}
}
Can you give a compelling reason to justify in converting from array to list? why not use only list or only array altogether? I use ArrayList in my answer below;
First of, the fillArray class. You do not need to fill with all zeros. Why even bother to fill it with a value that you will replace anyway?
public static ArrayList<Integer> fillArray(int size,int lowerBound,int upperBound){
ArrayList<Integer> a = new ArrayList<Integer>(size);
for (int count =0;count < size;count++){
Integer rand = new Integer(randomNum(lowerBound,upperBound));
a.add(rand);
}
return a;
}
Second, the sorting class. Your method as you said, searching for lowest value then do magic stuff and what not.
public static ArrayList<Integer> sorter(ArrayList<Integer> unsorted) {
ArrayList<Integer> sortedArray = new ArrayList<Integer>(unsorted.size());
while(!unsorted.isEmpty()) { //repeats until the unsorted list is empty
int minval = unsorted.get(0);
int removeIndex = 0;
for(int i=1;i<unsorted.size();i++)
if (unsorted.get(i)<minval) {
minval = unsorted.get(i);
removeIndex = i;
}
sortedArray.add(minval);
unsorted.remove(removeIndex);
}
return sortedArray;
}
main method to test it
public static void main(String[] args) {
ArrayList<Integer> a = fillArray(20,1,25);
System.out.println("unsorted array");
for (Integer c : a)
System.out.print(c + ";");
ArrayList<Integer> b = sorter(a);
System.out.println("\nnew unsorted array");
for (Integer c : a)
System.out.print(c + ";");
System.out.println("\nsorted array");
for (Integer c : b)
System.out.print(c + ";");
}
this outputs
unsorted array
22;2;23;22;13;12;4;1;7;14;25;18;9;12;3;8;20;3;1;20;
new unsorted array
sorted array
1;1;2;3;3;4;7;8;9;12;12;13;14;18;20;20;22;22;23;25;
Separate out the "find the smallest" and "insertion/deletion" from arrays into two methods and then use them.
This way the code will be more manageable. Below is a sample find_min method.
int find_min(int[] array, int start) {
int min = Integer.MAX_VALUE;
for(int i = start; i < array.length; ++i)
if(array[i] < min)
min = array[i] ;
return min;
}
Now in the sorting routine, use the find_min to find the minimum element and insert it to new array and then delete the minimum element from the original array. However, this method does not return the index of the minimum element. So, I suggest you to modify it to return the index and the element as a pair of int values.
Your sorting routine will look something like this :
new_array := []
while(length(original_array) > 0)
min, min_index := find_min(original_array)
new_array.append(min)
original_array.delete(min_index)
You can use something like this to return an int pair :
class IntPair {
int min;
int index;
public IntPair(int x, int y) { this.min=x; this.index=y; }
public int get_min() { return min; }
public int get_min_index() { return index; }
}
Also, since you will de doing insertion and deletion, use ArrayList instead. It has methods to remove element at a particular index and append elements to it.
Note: Your approach outlined is close to Selection Sort algorithm in which we divide the array into two parts (sorted left part and unsorted right part) and repeatedly pick the smallest element from the right of the array and swap it with the left part's rightmost element.
min := array[0]
for(i := 0; i < array.length; ++i)
for(j := i+1; j < array.length; ++j)
if(array[j] < min)
min = array[j]
break
swap(array[i], array[j])
In this case, you dont need two arrays and you dont need to delete or insert elements into an array either.
Related
I am trying to program a Java Code in which, given the lenght of an int array and a min and max values it returns an random array values.
I am trying to program it in the most simple way, but I am still not getting how the programming process works.
What I have tried is the following:
import java.util.Random;
public class RandomIntArray {
public static void main(String[] args){
System.out.println(createRandom(10));
}
public static int[] createRandom(int n) {
Random rd = new Random();
int[] array = new int[n];
int min = 5;
int max = 99;
for (int i = 0; i < array.length; i++) {
array[i] = rd.nextInt();
while (array[i] > min) ;
while (array[i] < max) ;
}
return array;
}
}
public static int[] createRandom(int n) {
Random rd = new Random();
int[] array = new int[n];
int min = 5;
int max = 10;
for (int i = 0; i < array.length; i++) {
array[i] = rd.nextInt(max-min+1) + min;
System.out.print(array[i] +" ");
}
return array;
}
public static void main(String[] args){
createRandom(5);
}
Try using IntStream to achieve what you want
public static void main(String[] args) {
int[] arr = createRandom(10);
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
public static int[] createRandom(int n) {
Random r = new Random();
int min = 5;
int max = 99;
return IntStream
.generate(() -> r.nextInt(max - min) + min)
.limit(n)
.toArray();
}
The first thing we must adjust is the random number generation. It appears you specify a min and max, so a number must be generated in with these bounds. We can use the Random.nextInt(int bound) method to set a range equal to max - min. However, this range will start from 0, so we must add your min value to make the bound complete. Using this process will eliminate the need for the existing while loops. See this question for more on this.
Now, every value in the array will be generated as
array[i] = rd.nextInt(max - min) + min
When trying to print array elements, a System.out.println() statement with the variable name of the array will print a memory address of the array. This will NOT print the entire array of values.
We must instead iterate over the elements to print them. It would be best to use a for loop to do this, but your program could generate an array of any size. So, we should use a for-each loop instead as follows:
for (int num : createRandom(10)) {
System.out.println(num);
}
This for-each is saying "for each int in the array returned by createRandom(10), refer to is as variable num and print it."
This is the final code:
import java.util.Random;
public class RandomIntArray {
public static void main(String[] args){
for (int num : createRandom(10)) {
System.out.println(num);
}
}
public static int[] createRandom(int n) {
Random rd = new Random();
int[] array = new int[n];
int min = 5;
int max = 99;
for (int i = 0; i < array.length; i++) {
array[i] = rd.nextInt(max - min) + min;
System.out.println(array[i]);
}
return array;
}
}
This question already has answers here:
Finding Duplicates in Array and printing them only Once
(6 answers)
Closed 4 years ago.
I have made the following program and implemented the merge sort where it sorts an array that the user fills and then picks any duplicate values from the array. However, I have a small problem in the main method. Example: I input the number 4 three times and it would display "duplicate: 4" two times; my goal here is to let it display only once, irrelevant of how many duplicates of 4 there are. Thanks guys.
import java.util.*;
`public class Question6` {
static void mergeSort(int arr1[], int o, int k, int x) {
int num1 = k - o + 1;
int num2 = x - k;
int temp1[] = new int [num1]; //creation of two temporary arrays to store in
int temp2[] = new int [num2];
for (int i=0; i<num1; ++i) //for loops to copy the data to the temporary arrays
temp1[i] = arr1[o + i];
for (int j=0; j<num2; ++j)
temp2[j] = arr1[k + o + j];
int i = 0, j = 0; //starting position of temporary arrays
int s = l; //starting position of the merged two temporary arrays
while (i < num1 && j < num2) {
if (temp1[i] <= temp2[j]) {
arr1[s] = temp1[i];
i++;
}
else {
arr1[s] = temp2[j];
j++;
}
s++;
}
//code to copy elements from temp1
while (i < num1)
{
arr1[s] = temp1[i];
i++;
s++;
}
//code to copy elements from temp2
while (j < num2)
{
arr1[s] = temp2[j];
j++;
s++;
}
}
/
void forSorting(int arr2[], int o, int x) //main method that carries out merge sort
{
if (o < x)
{
// Find the middle point
int a = (o+x)/2;
// Sort first and second halves
forSorting(arr2, o, a);
forSorting(arr2, a+1, x);
// Merge the sorted halves
mergeSort(arr2, o, a, x);
}
}
public static void main(String[] args) {
Question6 qs = new Question6();
Scanner sc = new Scanner(System.in);
int [] duplicate = new int[10];
System.out.println("Please input the numbers to be checked for repetition.");
for(int x = 0; x < 10; x++)
{
duplicate[x] = sc.nextInt(); //filling array
}
int length = duplicate.length;
qs.forSorting(duplicate, 0, length-1); //calling method forSorting
System.out.println(Arrays.toString(duplicate)); //displays array
for (int count = 1; count < 10; count++)
{
if (duplicate[count] == duplicate[count - 1]) {
//displays the duplicates
System.out.println("Duplicate: " + duplicate[count]);
}
}
}
}
I would try to go this way:
If the array has length 1, then there is no duplicate
If the array has length > 1, then iterate over the elements
The first element cannot be a duplicate
If the next element (assuming end of array not reached) has the same value as the current one, I have found a duplicate. Add the duplicate into something Set-like.
Continue with the next iteration.
After the iteration over the array is done, print all elements of the Set-like structure.
Disclaimer: Still very new to code and have only basic skills with java. Trying to learn as much as i can on my own and from others. Not currently studying at uni.
Hello everyone.
I am trying to create an array with a small capacity (5 integers) to store a randomly generated integer in each array element. The randomly generated integer is in a set range (0-75) which ive no issue with.
What i cant figure out how to do is how to Generate a new integer, then check it against the current existing integers in each array element, before storing it and moving on to the next.
What i tried was this:
public class ItemSet
{
public static void main(String []args)
{
int[] itemSet;
itemSet = new int[5];
itemSet[0] = 0; /* to initialise the array elements. Im not sure if i actually have to do this or not */
itemSet[1] = 0;
itemSet[2] = 0;
itemSet[3] = 0;
itemSet[4] = 0;
int count = 1;
int assignItem = 0;
int countTwo = 1;
while (count > 5) {
while (countTwo == 1) {
assignItem = (int)(Math.random()*76);
// here is where i get totally lost
if (assignItem.compareTo(itemSet)) {
countTwo = 1;
} else {
itemSet[(count--)] = assignItem;
countTwo = 0;
}
}
count = count++;
}
}
}
Ive been looking at this so long my head is starting to hurt. I'd appreciate any advice you can give me. :) Thank you in advance. xx
Edit: Couldnt find the solution i needed in any of the "how can i test if an array contains a certain value" type questions, because i need to be able to have the number randomise again before it stores itself in the array element if it does happen to be the same as another previously generated integer.
You are doing too much to just fill an array. To fill an array, try using a "for" loop like so:
public class ItemSet {
public static void main(String []args) {
int[] itemSet;
itemSet = new int[5];
int count = 1;
int assignItem = 0;
int countTwo = 1;
for (int i = 0; i < itemSet.length; i++) {
itemSet[i] = (int) (Math.random() * 76);
}
}
}
To print the values stored in the array, try using an enhanced-for loop:
for (int element : itemSet) {
System.out.println(element);
}
To check the values BEFORE storing the next integer, (say to see ensure that the new stored value would be unique) you could use a nested for loop that starts at the value beneath the outer loop and walks backwards, comparing each value that came before to the value that was just stored, and if they are the same, it will decrement the outer counter which will then override the data on the next loop:
import java.util.Arrays; // you need this to use Arrays.toString()
public class ItemSet {
public static void main(String []args) {
int[] itemSet;
itemSet = new int[5];
int count = 1;
int assignItem = 0;
int countTwo = 1;
for (int i = 0; i < itemSet.length; i++) {
itemSet[i] = (int) (Math.random() * 76);
for (int j = i - 1; j >= 0; j--) {
if (itemSet[j] == itemSet[i]) {
System.out.println("Comparing " + itemSet[j] +
" and " + itemSet[i]);
i--;
break; // not really needed but illustrates a way to exit a loop immediately
}
}
}
// this is a handy way to print all the data in an array quickly
System.out.println(Arrays.toString(itemSet));
}
}
public static void main (String[] args){
//you dont need to initialize the array with zeros
int[] itemSet = new int[5];
int counter = 0;
while(counter < itemSet.length){
int random = (int)(Math.random() * 76);
//checks if the array already contains the random number
if(!Arrays.asList(itemSet).contains(random)){
itemSet[counter] = random;
counter++;
}
}
//print the array
for(int i : itemSet) System.out.println(i);
}
There are many ways you could solve this problem, I would suggest using a helping method that looks for duplicates in your array. This would be a working example:
public static void main(String[] args) {
int[] itemSet;
itemSet = new int[5];
int assignItem;
for (int i = 0; i < 5; i++) {
assignItem = (int)(Math.random()*76);
if(!duplicate(assignItem,itemSet,i)){
itemSet[i] = assignItem;
}
}
}
private static boolean duplicate(int assignItem, int[] itemSet, int i) {
for (int j = 0; j < i; j++) {
if (assignItem == itemSet[j])
return true;
}
return false;
}
The most straight forward way would be checking through the array for existing value before inserting the current random value.
Generate a random value
Check if value exists in array
If already exist in array, generate another value
If not exist in array, set value to current element
In codes:
public static void main(String[] args){
int idx = 0;
int[] myArray = new int[5];
Random rnd = new Random();
int val = rnd.nextInt(76);
do{
if(numExistInArray(val, myArray))
val = rnd.nextInt(76); //if val exist in array, generate another number
else
myArray[idx++] = val; //if val not exist in array, fill array
}while(idx != myArray.length); //do not exit loop till all numbers are filled
}
public static boolean numExistInArray(int val, int[] array){
for(int x=0; x<array.length; x++)
if(array[x] == val)
return true;
return false;
}
I had a hard time understanding what youre asking for but ill give it a go anyway hoping this is what you want:
for (int count = 0; count < 5 ; count++) {
assignItem = (int)(Math.random()*76);
if (assignItem==itemSet[count]&&itemSet[count]!=0) {
//If true do this
}
else {
itemSet[count] = assignItem;
}
}
Checking if the generated number is equal to a position and if the position is empty (0) if its not equal (a new number) then it will assign value to your array.
If you know your set range (which is 0-75) and space isn't an issue, I would suggest maintaining a pool of unused integers. This would guarantee each value is unique, and would avoid iterating over your array of integers to check for duplicates:
public static void main(String[] args) {
List<Integer> unusedNumbers = new ArrayList();
// Populate list with values
for (int i = 0; i <= 75; i++) unusedNumbers.add(i);
int[] itemSet = new int[5];
for (int i = 0; i < 5; i++) {
int randomIndex = (int) (Math.random() * unusedNumbers.size());
int randomInt = unusedNumbers.remove(randomIndex);
itemSet[i] = randomInt;
}
}
Im trying to generate an array with 1000 integers of non-repeating numbers in ascending order from 0 to 10,000
So far what I have is:
public static void InitArray(int[] arr) { // InitArray method
int i, a_num; // int declared
Random my_rand_obj = new Random(); // random numbers
for (i = 0; i <= arr.length-1; i++) // for loop
{
a_num = my_rand_obj.nextInt(10000); // acquiring random numbers from 0 - 10000
arr[i] = a_num; // numbers being put into array (previoulsy declared of size 1000)
}
}
public static void ShowArray(int[] arr) { // ShowArray method
int i; // int declared
for (i = 0; i <= arr.length-1; i++) { // for loop
System.out.print(arr[i] + " "); // show current array content
}
System.out.println(); // empty line
}
public static void Sort(int[] arr) { // SortArray method
int i, min, j; // int decalred
for (i = 0; i < arr.length-1; i++) { // for loop
min = i; // min is i
for (j = i + 1; j < arr.length; j++) { // nested for loop
if (arr[j] < arr[min]) { // if statement
min = j; // j is the new minimum
}
}
int swap = arr[min]; // swap "method"
arr[min] = arr[i];
arr[i] = swap;
}
}
Is there any way to check the numbers are not repeating? Is there a function besides the random generator that will let me generate numbers without repeating? Thanks for any help
You can declare array of size 10,000
and init the array in away that each cell in the array will holds the value of it's index:
int [] arr= new int[10000];
for (int i=0 i < arr.length; i++){
arr[i] = i
}
Now you can shuffle the array using java Collections.
and take the first 1000 items from the array and sort then using java sort.
This will do I believe..
HashSet hs = new HashSet();
for(int i=0;i< arr.length;i++)
hs.add(arr[i]);
List<Integer> integers=new ArrayList<>(hs);
Collections.sort(integers);
A very simple solution is to generate the numbers cleverly. I have a solution. Though it may not have an even distribution, it's as simple as it can get. So, here goes:
public static int[] randomSortedArray (int minLimit, int maxLimit, int size) {
int range = (maxLimit - minLimit) / size;
int[] array = new int[size];
Random rand = new Random();
for (int i = 0; i < array.length; i++ ) {
array[i] = minLimit + rand.nextInt(range) + range * i;
}
return array;
}
So, in your case, call the method as:
int randomSortedArray = randomSortedArray(0, 10_000, 1_000);
It's very simple and doesn't require any sorting algorithm. It simply runs a single loop which makes it run in linear time (i.e. it is of time complexity = O(1)).
As a result, you get a randomly generated, "pre-sorted" int[] (int array) in unbelievable time!
Post a comment if you need an explanation of the algorithm (though it's fairly simple).
I have an array of size 1000. How can I find the indices (indexes) of the five maximum elements?
An example with setup code and my attempt are displayed below:
Random rand = new Random();
int[] myArray = new int[1000];
int[] maxIndices = new int[5];
int[] maxValues = new int[5];
for (int i = 0; i < myArray.length; i++) {
myArray[i] = rand.nextInt();
}
for (int i = 0; i < 5; i++) {
maxIndices[i] = i;
maxValues[i] = myArray[i];
}
for (int i = 0; i < maxIndices.length; i++) {
for (int j = 0; j < myArray.length; j++) {
if (myArray[j] > maxValues[i]) {
maxIndices[i] = j;
maxValues[i] = myArray[j];
}
}
}
for (int i = 0; i < maxIndices.length; i++) {
System.out.println("Index: " + maxIndices[i]);
}
I know the problem is that it is constantly assigning the highest maximum value to all the maximum elements. I am unsure how to remedy this because I have to preserve the values and the indices of myArray.
I don't think sorting is an option because I need to preserve the indices. In fact, it is the indices that I need specifically.
Sorry to answer this old question but I am missing an implementation which has all following properties:
Easy to read
Performant
Handling of multiple same values
Therefore I implemented it:
private int[] getBestKIndices(float[] array, int num) {
//create sort able array with index and value pair
IndexValuePair[] pairs = new IndexValuePair[array.length];
for (int i = 0; i < array.length; i++) {
pairs[i] = new IndexValuePair(i, array[i]);
}
//sort
Arrays.sort(pairs, new Comparator<IndexValuePair>() {
public int compare(IndexValuePair o1, IndexValuePair o2) {
return Float.compare(o2.value, o1.value);
}
});
//extract the indices
int[] result = new int[num];
for (int i = 0; i < num; i++) {
result[i] = pairs[i].index;
}
return result;
}
private class IndexValuePair {
private int index;
private float value;
public IndexValuePair(int index, float value) {
this.index = index;
this.value = value;
}
}
Sorting is an option, at the expense of extra memory. Consider the following algorithm.
1. Allocate additional array and copy into - O(n)
2. Sort additional array - O(n lg n)
3. Lop off the top k elements (in this case 5) - O(n), since k could be up to n
4. Iterate over the original array - O(n)
4.a search the top k elements for to see if they contain the current element - O(lg n)
So it step 4 is (n * lg n), just like the sort. The entire algorithm is n lg n, and is very simple to code.
Here's a quick and dirty example. There may be bugs in it, and obviously null checking and the like come into play.
import java.util.Arrays;
class ArrayTest {
public static void main(String[] args) {
int[] arr = {1, 3, 5, 7, 9, 2, 4, 6, 8, 10};
int[] indexes = indexesOfTopElements(arr,3);
for(int i = 0; i < indexes.length; i++) {
int index = indexes[i];
System.out.println(index + " " + arr[index]);
}
}
static int[] indexesOfTopElements(int[] orig, int nummax) {
int[] copy = Arrays.copyOf(orig,orig.length);
Arrays.sort(copy);
int[] honey = Arrays.copyOfRange(copy,copy.length - nummax, copy.length);
int[] result = new int[nummax];
int resultPos = 0;
for(int i = 0; i < orig.length; i++) {
int onTrial = orig[i];
int index = Arrays.binarySearch(honey,onTrial);
if(index < 0) continue;
result[resultPos++] = i;
}
return result;
}
}
There are other things you can do to reduce the overhead of this operation. For example instead of sorting, you could opt to use a queue that just tracks the largest 5. Being ints they values would probably have to be boxed to be added to a collection (unless you rolled your own) which adds to overhead significantly.
a bit late in answering, you could also use this function that I wrote:
/**
* Return the indexes correspond to the top-k largest in an array.
*/
public static int[] maxKIndex(double[] array, int top_k) {
double[] max = new double[top_k];
int[] maxIndex = new int[top_k];
Arrays.fill(max, Double.NEGATIVE_INFINITY);
Arrays.fill(maxIndex, -1);
top: for(int i = 0; i < array.length; i++) {
for(int j = 0; j < top_k; j++) {
if(array[i] > max[j]) {
for(int x = top_k - 1; x > j; x--) {
maxIndex[x] = maxIndex[x-1]; max[x] = max[x-1];
}
maxIndex[j] = i; max[j] = array[i];
continue top;
}
}
}
return maxIndex;
}
My quick and a bit "think outside the box" idea would be to use the EvictingQueue that holds an maximum of 5 elements. You'd had to pre-fill it with the first five elements from your array (do it in a ascending order, so the first element you add is the lowest from the five).
Than you have to iterate through the array and add a new element to the queue whenever the current value is greater than the lowest value in the queue. To remember the indexes, create a wrapper object (a value/index pair).
After iterating through the whole array, you have your five maximum value/index pairs in the queue (in descending order).
It's a O(n) solution.
Arrays.sort(myArray), then take the final 5 elements.
Sort a copy if you want to preserve the original order.
If you want the indices, there isn't a quick-and-dirty solution as there would be in python or some other languages. You sort and scan, but that's ugly.
Or you could go objecty - this is java, after all.
Make an ArrayMaxFilter object. It'll have a private class ArrayElement, which consists of an index and a value and has a natural ordering by value. It'll have a method which takes a pair of ints, index and value, creates an ArrayElement of them, and drops them into a priority queue of length 5. (or however many you want to find). Submit each index/value pair from the array, then report out the values remaining in the queue.
(yes, a priority queue traditionally keeps the lowest values, but you can flip this in your implementation)
Here is my solution. Create a class that pairs an indice with a value:
public class IndiceValuePair{
private int indice;
private int value;
public IndiceValuePair(int ind, int val){
indice = ind;
value = val;
}
public int getIndice(){
return indice;
}
public int getValue(){
return value;
}
}
and then use this class in your main method:
public static void main(String[] args){
Random rand = new Random();
int[] myArray = new int[10];
IndiceValuePair[] pairs = new IndiceValuePair[5];
System.out.println("Here are the indices and their values:");
for(int i = 0; i < myArray.length; i++) {
myArray[i] = rand.nextInt(100);
System.out.println(i+ ": " + myArray[i]);
for(int j = 0; j < pairs.length; j++){
//for the first five entries
if(pairs[j] == null){
pairs[j] = new IndiceValuePair(i, myArray[i]);
break;
}
else if(pairs[j].getValue() < myArray[i]){
//inserts the new pair into its correct spot
for(int k = 4; k > j; k--){
pairs[k] = pairs [k-1];
}
pairs[j] = new IndiceValuePair(i, myArray[i]);
break;
}
}
}
System.out.println("\n5 Max indices and their values");
for(int i = 0; i < pairs.length; i++){
System.out.println(pairs[i].getIndice() + ": " + pairs[i].getValue());
}
}
and example output from a run:
Here are the indices and their values:
0: 13
1: 71
2: 45
3: 38
4: 43
5: 9
6: 4
7: 5
8: 59
9: 60
5 Max indices and their values
1: 71
9: 60
8: 59
2: 45
4: 43
The example I provided only generates ten ints with a value between 0 and 99 just so that I could see that it worked. You can easily change this to fit 1000 values of any size. Also, rather than run 3 separate for loops, I checked to see if the newest value I add is a max value right after I add to to myArray. Give it a run and see if it works for you