Java int Array: Find Average, Min/Max, Sort - java

Edit: I need to do the following with the array: sort, find minimum, find maximum, find the average.
1) How do I properly access the methods in the other class 2) What variables do I need to initialize in order to make my methods work (since I got the examples from Google)
I've tried to find examples of how to work with the numbers in an array, but I find it difficult to figure out considering the code is working with different variable names and is largely unorganized and not commented.
This is what I have so far in my methods class:
//Grades Array
int[] score = {70,90,80,85,65,55,100,70,40,77,66,55,44};
int number;
//Get
public int getNumber(){
return number;
}
//Average Grade
public static double average(int[] score, int number)
{
double average = 0;
if (score.length > 0)
{
average = number / score.length;
}
return average;
}
Here is my Main class:
public class Main {
public static void main(String[] args) {
//Average Method
OtherMethods average = new OtherMethods();
int[] number = null;
OtherMethods.average(number, 0);
System.out.println(number);
}
}
So as you can see I'm all over the place. It's largely a patchwork of examples I've tried to apply.
This is the Sort code I'm using. Adhering my variables to the ones used here would be advantageous, of course, but I'm just not sure where to begin.
//Ascending Sort Method
public static void sort(int[] score, int number)
{
for(i=0; i < num-1; i++) //For each sublist
{
min = list[i];
position = i;
for (j=i+1; j < num; j++) //Find minimum
{
if (list[j] < min)
{
min = list[j];
position = j;
}
}
temp = list[position]; //Swap
list[position] = list[i];
list[i] = temp;
}
}
Any help would be greatly appreciated.

If you're using Java 8+, Check out the functional streams and in particular IntStream.
For Example, to min/max/average:
int min = IntStream.of(score)
.min(); // or .max() or .average()
and to sort:
score = IntStream.of(score)
.sorted()
.toArray();

If your trying to sort the numbers you can do something as simple as the bubble sort, which is fairly strait forward compare n to n+1 and switch if need be:
void bubbleSort(int ar[])
{
for (int i = (ar.length - 1); i >= 0; i--)
{
for (int j = 1; j ≤ i; j++)
{
if (ar[j-1] > ar[j])
{
int temp = ar[j-1];
ar[j-1] = ar[j];
ar[j] = temp;
} } } }
or like you did above the selection sort:
void selectionSort(int[] ar){
for (int i = 0; i ‹ ar.length-1; i++)
{
int min = i;
for (int j = i+1; j ‹ ar.length; j++)
if (ar[j] ‹ ar[min]) min = j;
int temp = ar[i];
ar[i] = ar[min];
ar[min] = temp;
} }
Another thing the way you currently have this set up your getNumber() function has no real use seeing that your number variable is global to begin with.
If you want more help you will have to come up with an actual question.

Related

One method policy in Java

I need some help. My professor give us an assignment that we need to "extract" these codes into ONE METHOD ONLY. Is there a way to do it? It's a heap code sorting algorithm. I'm currently do have a little knowledge about programming so bear with me guys. Can you help me?
import java.util.Arrays;
import java.util.Scanner;
class HeapSort {
private static Scanner sc;
public static void main(String args[]) {
sc = new Scanner(System.in);
System.out.println("Enter no of terms");
int n = sc.nextInt();
System.out.println("Enter the terms");
int arr[] = new int[n];
for (int i = 0; i < n; i++)
arr[i] = sc.nextInt();
System.out.println("The unsorted array is:");
System.out.println(Arrays.toString(arr));
heap(arr);
System.out.println("The sorted array is:");
System.out.println(Arrays.toString(arr));
}
static void heapify(int a[], int n, int i) {
int max, child;
child = 2 * i + 1;
max = i;
if (child < n)
if (a[child] > a[max])
max = child;
if (child + 1 < n)
if (a[child + 1] > a[max])
max = child + 1;
if (max != i) {
int temp = a[i];
a[i] = a[max];
a[max] = temp;
heapify(a, n, max);
}
}
static void buildheap(int a[]) {
for (int i = a.length / 2 - 1; i >= 0; i--)
heapify(a, a.length, i);
}
static void heap(int a[]) {
buildheap(a);
for (int i = a.length - 1; i >= 1; i--) {
int temp = a[0];
a[0] = a[i];
a[i] = temp;
heapify(a, i, 0);
}
}
}
You get there by simply replacing each method invocation with the actual body of the method. Of course, that will quickly lead to all kinds of confusion, given the poor naming of method parameters.
But the real challenge here (and probably your actual homework) is that you have to rework that heapify() method to not use recursion. In other words: you have to do the heap sort without using recursion. You can find some guidance here for example.
And of course: this code is already hard to read. Forcing all code into a single method will make it unreadable and not human comprehensive. It is like the exact opposite of good practices!
One thing you can do is replace all the code in each method to where the method is being called.
For example, instead of calling heap(arr) you can move all the code up to the place where heap(arr) is being called and continue to do so with the rest of the code.

Longest Increasing SubSequence using Binary Search

I am trying to implement The Longest Increasing SubSequence using Binary Search. Well I have coded the algorithm and my test cases are getting satisfied but when I submit the code,it is failing for some test cases like for example for the following list,
29471 5242 21175 28931 2889 7275 19159 21773 1325 6901, the answer should be 4 but I am getting 5.Below is my code,
import java.util.Scanner;
public class LongestIncreasingSubSequence {
public static int BS(int[] arr,int low,int high,int key){
int mid;
while ((high - low) > 1) {
mid = (int) Math.ceil((low + high) / 2);
if (arr[mid] >= key) {
high = mid;
} else {
low = mid;
}
}
return high;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n;
n = sc.nextInt();
int arr[] = new int[n];
int LS[] = new int[arr.length];
int count = 1;
for (int i = 0; i < n; i++) {
arr[i] = sc.nextInt();
}
LS[0] = arr[0];
for (int i = 1; i < arr.length; i++) {
if (arr[i] < LS[0]) {
LS[0] = arr[i];
} else if (arr[i] > LS[count-1]) {
LS[count++] = arr[i];
} else {
LS[BS(arr,0,count-1,arr[i])] = arr[i];
}
}
System.out.println(count);
}
}
So can anyone please tell me where I am going wrong.Thanks in advance.
There is a bug here:
LS[BS(arr,0,count-1,arr[i])] = arr[i];should be
LS[BS(LS,0,count-1,arr[i])] = arr[i]; instead, because we need to update the array with the smallest value for each length of an increasing sub sequence (that is, LS), not the original one.
With this change, it works properly on your test case (I haven't tested it on anything else, but the algorithm looks correct to me now).

Erroneous behaviour of Java 8 Stream.sum()

Today while solving this question on HackerRank I used Array stream .sum() function to sum all the entries and proceeded with my algorithm. But for sum reason I found that my algorithm fails for some cases. I used diff to find out it passes 99% cases and for 1% the output is nearly equal but is less than the original answer. That's why I replaced the stream .sum() with a for loop and unexpectedly it passed all the test cases. I tried but couldn't ascertain this uncertain behaviour.
My implementation using stream.sum() :
public class MandragoraForest {
public static void main(String[] args) {
InputReader in = new InputReader(System.in);
for (int i = in.nextInt(); i > 0; i--) {
int number = in.nextInt();
int[] h = new int[number];
for (int j = 0; j < number; j++) h[j] = in.nextInt();
System.out.println(new MandragoraForestSolver().solve(h));
}
}
}
class MandragoraForestSolver {
public long solve(int[] h) {
if (h.length==1) return h[0];
Arrays.parallelSort(h);
long sum = Arrays.stream(h)
.sum();
long ans = -1;
for (long i=0, strength = 2; i<h.length; i++, strength++) {
sum -= h[(int)i];
ans = Math.max(ans, strength * sum);
}
return ans;
}
}
Implementation without Java stream :
public class MandragoraForest {
public static void main(String[] args) {
InputReader in = new InputReader(System.in);
for (int i = in.nextInt(); i > 0; i--) {
int number = in.nextInt();
int[] h = new int[number];
long sum = 0;
for (int j = 0; j < number; j++) {
h[j] = in.nextInt();
sum += h[j];
}
System.out.println(new MandragoraForestSolver().solve(h, sum));
}
}
}
class MandragoraForestSolver {
public long solve(int[] h, long sum) {
if (h.length==1) return h[0];
Arrays.parallelSort(h);
long ans = -1;
for (long i=0, strength = 2; i<h.length; i++, strength++) {
sum -= h[(int)i];
ans = Math.max(ans, strength * sum);
}
return ans;
}
}
Is there something that I'am missing out ? What could be the reason for this behaviour?
There is one significant difference between using a stream and a loop - the possibility of arithmetic overflow.
Arrays.stream(int[]) returns an IntStream, whose sum() method returns an int result. If the sum exceeds Integer.MAX_VALUE, a silent integer overflow will occur.
However your loop sums by adding int values to a long total, which would not suffer from arithmetic overflow.
The sum of integers in one of the tests must exceed Integer.MAX_VALUE, testing that a long is used to (correctly) calculate the total.
If you want to use a stream to sum, you need to convert the IntStream to a LongStream, which you can do like this:
long sum = Arrays.stream(big).asLongStream().sum();

Given an array of integers, find out the third largest value in the array

public int thirdLargest(int[] arr){
int f_l = arr[0];
int s_l = arr[0];
int t_l = arr[0];
for(int i=1;i<arr.length;i++)
{
if (f_l < arr[i]){
t_l = s_l;
s_l = f_l;
f_l = arr[i];
}
else if (s_l < arr[i]){
t_l = s_l;
s_l = arr[i];
}
else if (t_l < arr[i]){
t_l = arr[i];
}
}
return t_l;
}
my code didn't passes some cases,any suggestion?
parameter {24,27,30,31,34,37,40,42}' , passes
parameter {2,-1,-2,-3,-4,-5}' , fails
This is simply cause by the fact that you initialize all values to arr[0]. If all elements are smaller than arr[0] this code won't update the values, even though the second-largest element for example wouldn't be arr[0]. Instead initialize the variables for the third/second/largest value with Integer.MIN_VALUE and start the search with the first element (index = 0) instead of the second.
There is actually a well-known algorithm for this, which is more generic than yours. It is called quick-select and looks like a quick sort with an optimization making it faster (linear time in average) : since we don't need to sort the array, we just recurse on the part of the array containing the index we are looking for (in your case, third item so index 2).
Here is an implementation in Java :
private static final Random rd = new Random();
public static int kthElement(int[] arr, int k) {
return kthElement(arr,k,0,arr.length);
}
private static T kthElement(int[] arr, int k, int min, int max) {
if (min < max - 1) {
int p = pivot(arr,min,max);
return p == k - 1 ? arr[p] :
p < k - 1 ? kthElement(arr,k,p + 1,max) : kthElement(arr,k,min,p);
}
return arr[min];
}
private static int pivot(int[] arr, int min, int max) {
int pivot = min + rd.nextInt(max - min);
swap(arr,pivot,max - 1);
pivot = min;
for (int i=min ; i<max ; i++)
if (arr[i] < arr[max - 1]) swap(arr,i,pivot++);
swap(arr,max - 1,pivot);
return pivot;
}
private static void swap(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
Well, as an alternative to your working code, here is a solution that will allow you to find the Nth largest integer in your array using Collections to do the heavy lifting:
import java.util.Arrays;
import java.util.Collections;
public class ArrayNthLargest {
public static int getNthLargest(int[] arrayInput, int n) {
Integer[] sortedArray = new Integer[arrayInput.length];
for (int i = 0; i < arrayInput.length; i++) {
sortedArray[i] = new Integer(arrayInput[i]);
}
Arrays.sort(sortedArray, Collections.reverseOrder());
return (sortedArray[n - 1]);
}
public static void main(String[] args){
int nth = new Integer(0);
int n = new Integer(3);
int[] testArray = {1,2,3,4,5,6,23,44,55,8,1};
nth = getNthLargest(testArray, n);
System.out.printf("The %d sorted array value is %d", n, nth);
}
}
This was actually an interesting question to me to do in O(n) complexity. I hope this solution is order n. I used an ArrayList as a stack (since Stack object won't allow addition of items in specific incidences (I've generalized it).
public int thirdLargest(int[] arr){
public int N_TH = 3; // Assuming this is nth largest you want
public ArrayList<Integer> largest = new ArrayList<Integer>(N_TH);
for(int i = 0;i<N_TH;i++)
largest.add(0); // initialize the ArrayList
for(int i = 0;i<arr.length;i++) {
for(int j=0;j<largest.size();j++){
if(arr[i] >= largest.get(j)) {
// Add the item at the correct index
// Pop the last element
largest.remove(largest.size()-1);
largest.add(j,arr[i]);
break;
}
}
}
return largest.get(N_TH);
}
Let me know if you find any problems with it, I might have mistyped part of trying to put it in OP's method.
EDIT won't work with negative numbers at the moment. You can find the smallest value in arr and initialize largest with that value. Then it'll also with negative numbers

Using a selection sort to sort an array of objects?

This is a homework question, so I don't expect to have it done for me. That being said, I have ran into a problem. I understand selection sorting and can write a code that will do it for me, but I don't know how to access the specific part of the object that I need to sort. In this case, it is student ID numbers.
I have been given a partial program, a student class(creates students according to the values in another file we are given).
import TextIO.*;
public class StudentQEg {
static void sortByID(int[] A) {
for (int lastPlace = A.length-1; lastPlace > 0; lastPlace--) {
int maxLoc = 0;
for (int j = 1; j <= lastPlace; j++) {
if (A[j] > A[maxLoc]) {
maxLoc = j;
}
}
int temp = A[maxLoc];
A[maxLoc] = A[lastPlace];
A[lastPlace] = temp;
}
}
public static void main(String args[]){
StudentQ[] students;
int nbrstuds;
String name;
int id;
double avg;
TextIO.readUserSelectedFile();
nbrstuds=TextIO.getlnInt();
students=new StudentQ[nbrstuds];
for (int i=0; i<nbrstuds; i++) {
name=TextIO.getWord();
id=TextIO.getInt();
avg=TextIO.getlnDouble();
students[i]=new StudentQ(name,id,avg);
}
sortByID(students);
for (int i=0; i<nbrstuds; i++) {
TextIO.putln(students[i]);
}
}
}
This obviously throws the error that sortByID([int[]) isn't applicable for the args (StudentQ[]). Any attempt I have tried to reference StudentQ[].id has been unsuccessful, so any help is appreciated.
Why don't you just change the method signature from static void sortByID(int[] A) to static void sortByID(StudentQ[] students) ?
After changing the method signature, you can do something like this for comparison:
if (students[j].id > students[maxLoc].id)
The method sortById should take in an array of StudentQ instead of array of int. Integers don't have an id that you can use as the sort parameter. StudentQ[].id will not work since the field id is on StudentQ. Here's a snippet of the refactoring required to get this to work:
static void sortByID(StudentQ[] A) {
for (int lastPlace = A.length-1; lastPlace > 0; lastPlace--) {
int maxLoc = 0;
for (int j = 1; j <= lastPlace; j++) {
if (A[j].id > A[maxLoc].id) {
maxLoc = j;
}
}
StudentQ temp = A[maxLoc];
A[maxLoc] = A[lastPlace];
A[lastPlace] = temp;
}
If you're interested in exploring a more java-esque approach, consider using a comparator.

Categories

Resources