Iterating through ArrayList to get 5 Largest Numbers - java

Yes, this is homework, but I need some help with it. I have been able to make it sort through the highest number, but none of the numbers are correct after that. List of numbers: http://pastebin.com/Ss1WFGv1
Right now, we are learning arrays, so is this simply trying to shoot a fly with a cannonball?
package hw2;
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.ArrayList;
public class HW2 {
public static ArrayList<Integer> nums1 = new ArrayList<Integer>();
public static int size = 0;
public static void main(String[] args) throws Exception {
ArrayList<Integer> sortedNums = new ArrayList<Integer>();
readFile();
System.out.println("Name: Jay Bhagat" + "\n" + "Email: xxxxxx");
size = nums1.size();
for(int l = 0; l<=10;l++){
nums1.set(sortThis(nums1, l), 90009);
System.out.println("\n\n");
}
// for (int k = 0; k <= size - 1; k++) {
// System.out.println("Number " + (k + 1) + sortedNums.get(k));
//
// }
}
public static void readFile() throws Exception {
BufferedReader reader = new BufferedReader(new FileReader("L:\\numbers.txt"));
while (reader.readLine() != null) {
nums1.add(Integer.parseInt((reader.readLine())));
}
reader.close();
}
public static int sortThis(ArrayList<Integer> current, int offset) {
int j = 0;
int tempNum = 0;
int curNum = 0;
int finalIndex = 0;
int prevIndex = 0;
int curIndex = 0;
for (j = 0; j < size-offset; j++) {
curIndex = j;
nums1.trimToSize();
curNum = current.get(j);
//Thread.sleep(1000);
if(curNum!=90009){
if (curNum > tempNum) {
tempNum = curNum;
System.out.println(tempNum);
prevIndex = j;
finalIndex = prevIndex;
}
if (curNum < tempNum) {
finalIndex = prevIndex;
}
}
}
return finalIndex;
}
}

An approach that lets you make just one pass through the list and doesn't require sorting:
Declare an array of 5 integers: int[] largest = new int[5];
Put the first 5 elements in the ArrayList into largest.
Starting with the 6th element, look at each element N in the ArrayList, and if N is larger than any element in largest, throw out the smallest number currently in largest and replace it with N.
If you need to exclude duplicates, the algorithm can be modified easily (just skip over any ArrayList element that's already in largest).

Why not use Collections.sort(List list) or Arrays.Sort(arr). This will save much of effort. Or is it part of your task?

Assuming your collection is sorted, and you want the last 5 elements, try this out:
for (int i = sortedNums.size() - 5; i < sortedNums.size(); ++i) {
System.err.println(sortedNums.get(i));
}

How I would go about doing this:
Create a temporary ArrayList, as a copy of the initial one.
After each largest element is found, remove it from the temporary ArrayList and add it to your 5 largest numbers
Repeat until complete
edit* This does not require your elements to be sorted, and has a fairly poor efficiency as a result

I assume you do not have the liberty to use sort and suchlike, considering this is a homework. So here is outline of an algorithm that you can try to implement
create an array of five integers (we will keep this sorted)
for each element in the list
find the index of the element in the array that it is greater than
if no such element exists in the array (i.e. it is smaller than all elements in the array)
continue on to the next element in the list
else
push all elements in the array to one index below, letting them fall off the
edge if need be (e.g. if the number in list is 42 and the array has
45 and 40 at index 3 and 2 respectively then
move arr[1] to arr[0], and arr[2] (40) to arr[1] and set arr[2] = 42)
end if
end for
At the end the array will have the five elements
I will leave one question for you to answer (it is important): what should you set the array to initially?

You only need two lines of code:
Collections.sort(nums1);
List<Integer> high5 = nums1.subList(nums1.size() - 5, nums1.size());
If you must "do it yourself", the simplest way to sort is a bubble sort:
iterate over the list
swap adjacent numbers if they are in the wrong order
repeat n times
Not efficient but very easy to code.

Related

Trying to create a array with the intersection of two arrays but fails at creating array with the proper structure

So, I am trying to create 2 randomly generated arrays,(a, and b, each with 10 unique whole numbers from 0 to 20), and then creating 2 arrays with the info of the last two. One containing the numbers that appear in both a and b, and another with the numbers that are unique to a and to b. The arrays must be listed in a "a -> [1, 2, 3,...]" format. At the moment I only know how to generate the 2 arrays, and am currently at the Intersection part. The problem is, that I can create a array with the correct list of numbers, but it will have the same length of the other two, and the spaces where it shouldn't have anything, it will be filled with 0s when its supposed to create a smaller array with only the right numbers.
package tps.tp1.pack2Arrays;
public class P02ArraysExtractUniqsAndReps {
public static void main(String[] args) {
int nbr = 10;
int min = 0;
int max = 20;
generateArray(nbr, min, max);
System.out.println();
}
public static int[] generateArray(int nbr, int min, int max) {
int[] a = new int[nbr];
int[] b = new int[nbr];
int[] s = new int[nbr];
s[0] = 0;
for (int i = 0; i < a.length; i++) {
a[i] = (int) (Math.random() * (max - min));
b[i] = (int) (Math.random() * (max - min));
for (int j = 0; j < i; j++) {
if (a[i] == a[j]) {
i--;
}
if (b[i] == b[j]) {
i--;
}
}
}
System.out.println("a - > " + Arrays.toString(a));
System.out.println("b - > " + Arrays.toString(b));
for (int k = 0; k < a.length; k++) {
for (int l = 0; l < b.length; l++) {
if (a[k] == b[l]) {
s[l] = b[l];
}else {
}
}
}
System.out.println("(a ∪ (b/(a ∩ b)) - > " + Arrays.toString(s));
return null;
}
public static boolean hasValue(int[] array, int value) {
for (int i = 0; i < array.length; i++) {
if (array[i] == value) {
return true;
}
}
return false;
}
}
Is there any way to create the array without the incorrect 0s? (I say incorrect because it is possible to have 0 in both a and b).
Any help/clarification is appreciated.
First, allocate an array large enough to hold the intersection. It needs to be no bigger that the smaller of the source arrays.
When you add a value to the intersection array, always add it starting at the beginning of the array. Use a counter to update the next position. This also allows the value 0 to be a valid value.
Then when finished. use Array.copyOf() to copy only the first part of the array to itself, thus removing the empty (unfilled 0 value) spaces. This works as follow assuming count is the index you have been using to add to the array: Assume count = 3
int[] inter = {1,2,3,0,0,0,0};
inter = Arrays.copyOf(inter, count);
System.out.println(Arrays.toString(inter);
prints
[1,2,3]
Here is an approach using a List
int[] b = {4,3,1,2,5,0,2};
int [] a = {3,5,2,3,7,8,2,0,9,10};
Add one of the arrays to the list.
List<Integer> list = new ArrayList<>();
for(int i : a) {
list.add(i);
}
Allocate the intersection array with count used as the next location. It doesn't matter which array's length you use.
int count = 0;
int [] intersection = new int[a.length];
Now simply iterate thru the other array.
if the list contains the value, add it to the intersection array.
then remove it from the list and increment count. NOTE - The removed value must be converted to an Integer object, otherwise, if a simple int value, it would be interpreted as an index and the value at that index would be removed and not the actual value itself (or an Exception might be thrown).
once finished the intersection array will have the values and probably unseen zeroes at the end.
for(int i = 0; i < b.length; i++) {
int val = b[i];
if (list.contains(val)) {
intersection[count++] = val;
list.remove(Integer.valueOf(val));
}
}
To shorten the array, use the copy method mentioned above.
intersection = Arrays.copyOf(intersection, count);
System.out.println(Arrays.toString(intersection));
prints
[3, 2, 5, 0, 2]
Note that it does not matter which array is which. If you reverse the arrays for a and b above, the same intersection will result, albeit in a different order.
The first thing I notice is that you are declaring your intersection array at the top of the method.
int[] s = new int[nbr];
You are declaring the same amount of space for the array regardless of the amount you actually use.
Method Arrays.toString(int []) will print any uninitialized slots in the array as "0"
There are several different approaches you can take here:
You can delay initializing the array until you have determined the size of the set you are dealing with.
You can transfer your content into another well sized array after figuring out your result set.
You could forego using Array.toString, and build the string up yourself.

Sqrt, and Math in Arrays

I'm having difficulty understand how to write this array. I need it to out-print 10x5 (50 elements total), and have the first 25 elements equal to the sqrt of the index that it is in, and the last 25 to equal 3 * the index. Yes, this is homework but I'm not asking for you to do it for me, I just need help! I'm getting errors when using Math saying that I cant use double and the double array together. Here is what I have so far:
public class snhu4 {
public static void main(String args[]) {
double alpha[][] = new double[10][5];
double[] sum, sum2;
for (int count=0; count<=25;count++) {
alpha[count]= Math.sqrt(count);
}
for (int count=26; count<=50;count++) {
alpha[count]= count *3;
}
for (int count=0; count<=50;count++) {
System.out.print(alpha[count]);
}
}
}
Because alpha is a multidimensional array, you can't refer to its elements like a normal array.
int myarray[][] = new int[2][2];
In the above example, the array myarray is multidimensional. If I wanted to access the second element in the first array, I would access it like this:
int myint = myarray[0][1];
You are trying to access a multidimensional array by using the access for a normal array. Change
alpha[count]
to
alpha[0][count]
or similar.
Read here for more information on multidimensional arrays.
you defined alpha as a 2D array with lets say 10 items in the first dimension and 5 in the second, and 5x10 is 50 elements.
When using your array to assign values to these elements, u must call upon the array using 2 indices, one for each dimension:
alpha[i][j] = /*double value*/; //with 0<=i<=9 and 0<=j<=4
So the first 25 elements going from left to right in dimension order is going to be:
[0to9][0] and [0to9][1] and [0to4][2]
the next 25 will be
[4to9][2] and [0to9][3] and [0to9][4]
from then on i cannot give you the answers to your homework, but the loops should look like this:
int j;
for(int i = 0; i<25; i++)
{
j=i/10; //integer division will return 0 for i<10, 1 for 10<i<20, etc..
alpha[i%10][j] = Math.sqrt(i);
}
and you can figure out the rest
The 10x5 appears to be an output constraint, not a design constraint.
You are using Java, so use Java constructs, not C-language constructs;
specifically store the values in a List not an array.
Here are some hints:
List<Integer> valuesList = new ArrayList<Integer>();
for (int index = 0; index < 25; ++index)
Integer currentValue = Math.sqrt(index);
valuesList.add(currentValue);
for (int index = 25; index < 50; ++index)
Integer currentValue = index * 3;
valuesList.add(currentValue)
int count = 1;
for (Integer current : valuesList)
if ((count % 5) == 0) // write a newline.
System.out.print(current);
++count

Numbers I can get by adding an array in java

I need to get a minimum number that I cant get by adding different numbers of an array. Basically if I have these numbers:1,1,1,5; I can get 1,2,3,5,6... but I cant get 4 so that is the number I am looking for. Now this is my code:
import java.util.Scanner;
public class Broj_6 {
public static void main(String[] args) {
Scanner unos = new Scanner(System.in);
int k;
int n = unos.nextInt();
int niz []= new int [n];
for(int i = 0;i<n;i++){
niz[i]=unos.nextInt();
}
BubbleSort(niz);
for(int i = 0;i<n;i++){
System.out.print(niz[i] + " ");
}
for(int br = 1;br<=10000;br++){
for(k = 1;k<n;k++){
if(niz[k]>br){
break;
}
}
int podniz [] = new int [k];
for(int i=0;i<podniz.length;i++){
niz[i] = podniz[i];
}
//This is where I will need my logic to go
}
}
static void BubbleSort (int [] niz){
int pom;
for(int i = 0;i<niz.length-1;i++){
for(int j = 0;j<niz.length-1-i;j++){
if(niz[j]>niz[j+1]){
pom = niz[j];
niz[j] = niz[j+1];
niz[j+1] = pom;
}
}
}
}
}
So the code goes by testing each number individually from 1 to 100000 and makes a subarray of all numbers given that are less than the number itself. Now here is the problem,I dont know how to mix and match the numbers in the subarray so it can get(or not get) the desired number. When every combination is tested and there is no desired number,I will break; the loop and print i. Just to clarify,I can only use addition,and each number can only go in once
You can achieve this as below:
Use two nested loops, like below to calculate the sum of different numbers:
List<Integer> additionList = new ArrayList<Integer>();
int []inputNumbers = .... // Logic to read inputs
for(int _firstIndex = 0; _firstIndex < totalInputs; _firstIndex++){
for(int _secondIndex = _firstIndex + 1; _secondIndex < totalInputs; _secondIndex++){
additionList.add(inputNumbers[_firstIndex]); // only because you have 1 in the sample output
additionList.add(inputNumbers[_firstIndex] + inputNumbers[_secondIndex ]);
}
}
Then sort additionList and look for any missing entry. The first missing entry will be your answer,
Sorting the whole array and then finding sum of all subarrays does solve the problem, but is costly: O(2n^2) ~ O(n^2).
More efficient way to solve this will be Kadane's Algorithm: http://en.wikipedia.org/wiki/Maximum_subarray_problem
What the algo does:
Start from first element and increase the array size (sub array) till you reach the sum you're desiring.
my_num = 1;
while(true){
if(sum_subarray) > my_num){
current position = new subarray;
}
and this subarray concept is calculated through Kadane's approach:
def sum_subarray(A):
sum_ending_here = sum_so_far = 0
for x in A:
sum_ending_here = max(0, max_ending_here + x)
sum_so_far = max(sum_so_far, sum_ending_here)
return sum_so_far
I couldn't solve the problem completely. 'my_num' mentioned here needs to be incremented from 1, and break when my_num > max_sum. I hope someone can add to it and make it compilable.
Note:
This will also take care if negative elements are present in array.

addition of combinations of two-dimensional array list

So the problem I'm working on solving involves an array list of array list of integers
. What is known: The number of elements in each ArrayList of integers. What is NOT known: How many ArrayList of Integers there actually are. I need suggestions for an algorithm that would sum the (ordered) elements of these arrays in every combination possible OF the arrays. In order to clarify what I mean by this let me give an example:
AoA = [[1,0,1,0],[0,1,0,1],[1,1,1,1],[0,0,0,0]];
Sum the elements of AoA[0] + AoA[1]; AoA[0]+AoA[2]; AoA[0]+AoA[3]; AoA[1]+AoA[2]; AoA[1]+AoA[3]; AoA[2]+AoA[3];
(4 choose 2)
So if anyone could code this simple version I'd be grateful as I'm struggling to do it. If anyone could code the more complex example where there's an unknown number of arrays in the AoA (so N choose 2), you'd be my hero.
TL;DR/edit
I need an algorithm to take n-choose-2 arrays from an array of arrays; sum the arrays (e.g. [1,2,3] + [1,2,3] = [2,4,6]); put the add the new summed array into an array of arrays.
If the 2 is fixed then the easiest thing I can think about is just generating the new array with N*(N-1)/2 rows, one for each sum and then using two variables to iterate through the original array with something like:s
int c = 0;
for (int i = 0; i < N; i++) {
for (int j = i + 1; j < N; j++) {
for (int k = 0; k < M; k++) {
sums[c][k] = AoA[i][k] + AoA[j][k];
}
c++;
}
}
Here's what I've got, took me a while but this will do what I was looking for:
it takes each combination of the arrays (t1, t2, t3, t4) and adds their elements and returns whatever combinatorial you choose for n, (in this example i left it as 3).
If there's any more optimizations you can see please feel free to add it. I'm a perl guy so making this work at all in Java was a real task.
import java.util.ArrayList;
public class testnCk {
public static void main(String[] args) {
ArrayList<int[]> sums = new ArrayList<int[]>();
int [] t1 = {1,1,0,0};
int [] t2 = {1,0,0,1};
int [] t3 = {0,0,0,0};
int [] t4 = {0,0,1,1};
ArrayList<int[]> testing = new ArrayList<int[]>();
testing.add(t1);
testing.add(t2);
testing.add(t3);
testing.add(t4);
int n = 3;
int i = -1;
int[] array = new int[4];
ArrayList<int[]> whatever = nCk(testing, sums, array, i, n);
for (int[] test1 : whatever)
{
for (int j = 0; j < test1.length; j++) {
System.out.print(test1[j]);
}
System.out.println();
}
}
public static ArrayList<int[]> nCk (ArrayList<int[]> arrayOfDiffPatterns, ArrayList<int[]> solutions, int[] tempsums, int i, int n)
{
n--;
for (int j=i+1; j<arrayOfDiffPatterns.size(); j++){
int[] array = tempsums.clone();
for (int k=0; k<arrayOfDiffPatterns.get(0).length; k++){
array[k] += arrayOfDiffPatterns.get(j)[k];
}
if(n>0){
nCk(arrayOfDiffPatterns, solutions, array, j, n);
}
else{
solutions.add(array);
}
}
return solutions;
}
}

Sort integer in Ascending Order - Java

I need help understanding how to sort numbers.
Below is what I have I came up with so far and it didn't work. Can you please point out the mistake and tell me what to do?
I saw some of you guys using java.util.Arrays . Can you describe to me its functions?
import static java.lang.System.*;
import java.util.*;
public class Lab07v2_Task10{
public static void main (String[] args){
Scanner orcho = new Scanner (in);
int quantity = 5;
int[] myArray = new int [quantity];
out.println("Please enter 5 numbers");
for(int count = 0; count<myArray.length; count++){
myArray[count] = orcho.nextInt();
}
int maxSoFar = myArray[0];
for(int count = myArray.length-1; count>=0; count--){
if(myArray[count] > maxSoFar){
maxSoFar = myArray[count];
}
out.println(maxSoFar);
}
}
}
No solution.
The idea is to take several steps, do a for-loop. And assume that you are in the middle. The first part already is sorted, the rest is to-be-done.
Then tackle the current element with respect to what already is sorted.
int maxSoFar = myArray[0];
for (int i = 1; i < myArray.length; i++) {
// The array 0, ..., i-1 is sorted
if (myArray[i] >= maxSoFar) {
// Still sorted
maxSoFar = myArray[i];
} else {
// myArray[i] must be shifted left
...
}
// Now the array 0, ..., i is sorted
}
This is a general trick: assume part is already done, tackle one small step, and let continue.
The java.util.Arrays.sort(int[]) method sorts the specified array of int into ascending numerical order.
try this out..
// sorting array
java.util.Arrays.sort(myArray);
// let us print all the elements available in list
System.out.println("The sorted int array is:");
for (int number : myArray) {
System.out.println("Number = " + number);
}
}
Arrays.sort is a method which is a utility method available in java.util package.
Where Arrays is a system defined Utility class which contains the mehtod sort(int[]) takes int[] (array) as an argument and after sorting this array, It re-assign Array.
For more deep Info Here or Official Java Docs
The way your program runs right now: it will print 5 numbers and the number that it prints is the highest number it finds at that iteration.
The way that you want it to work: sort 5 numbers from lowest to highest. Then print these 5 numbers. This is an implementation of bubble sort in your program:
for(int i = 0; i< myArray.length; i++){
for(int j = 0; j < myArray.length-1; j++){
if(myArray[j] > myArray[j+1]){ //if the current number is less than the one next to it
int temp = myArray[j]; //save the current number
myArray[j] = myArray[j+1]; //put the one next to it in its spot
myArray[j+1] = temp; //put the current number in the next spot
}
}
}
it is probably the easiest sort to understand. Basically, for as many times as the length of your array, comb over the numbers and bring the next highest number as far up as it can go.
When it's done sorting you can then print the numbers.

Categories