Finding Average of Array of integers using recursion - java

I'm trying to find the average of integers elements in an array using recursion. I know how to do it using loops, but I have to do it by recursion for my assignment, so what I tried to do is to find the sum of elements using recursion and then divide the sum by the length of the array. I wrote this code but it gives me a wrong result:
public int findAvg(int a[], int n)
{
int sum,avg;
if(n==1)
{
sum=a[0];
return sum;
}
else
{
sum=a[n-1]+findAvg(a,n-1);
}
avg = sum/n;
return avg;}
The calling of findAvg method in main class:
public class main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Recursive r = new Recursive ();
int integersArr [] = {1,2,3,4,5};
int max = r.findMax(integersArr,integersArr.length );
int avg = r.findAvg(integersArr, integersArr.length);
System.out.println("Maximum element = "+ max);
System.out.println("Average value of elements = "+ avg);
}
}
The console output:
Average value of elements = 1

First of all sum=a[n-1]+findAvg(a,n-1); is wrong, since if findAvg(a,n-1) returns the correct average for the first (n-1) elements, the sum should be a[n-1] + (n-1) * findAvg(a,n-1).
Second of all, you are losing precision when dividing integers in avg = sum/n; Consider using doubles.

First of all average of integers can be floating point. So make the return type of your function to float or double.
Now,
If you have set of n numbers with average of x and you want to add one more number to the set (say b). New average will be ((n * x) + b) / (n + 1). Use the same trick in your code.
public float findAvg(int a[], int n)
{
float sum,avg;
if(n==1)
{
sum=a[0];
}
else
{
// Calculate sum of n-1 numbers = (n-1) * (avg of n-1 numbers)
// and add nth number to it ( i.e. a[n-1])
sum= a[n-1]+ (n-1) * findAvg(a,n-1);
}
avg = sum/n;
return avg;
}

public double average(int y[], int i) {
double result;
result = (double)y[i] / (double)y.length;
if (i == 0)
return result;
else
return result + average(y, i-1);
}

public class main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Recursive r = new Recursive ();
int integersArr [] = {1,2,3,4,5};
int max = r.findMax(integersArr,integersArr.length );
int avg = r.findAvg(integersArr, integersArr.length);
System.out.println("Maximum element = "+ max);
System.out.println("Average value of elements = "+ avg);
}
}

Related

Fibonacci sequence - How to calculate the sum of the first 100 even-values Fibonacci numbers?

Fibonacci sequence is defined as a sequence of integers starting with 1 and 1, where each subsequent value is the sum of the preceding two I.e.
f(0) = 1
f(1) = 1
f(n) = f(n-1) + f(n-2) where n>=2
My goal is to calculate the sum of the first 100 even-values Fibonacci numbers.
So far I've found this code which works perfectly to calculate the sum of even numbers to 4million , however I'm unable to find edit the code so that it stops at the sum of the 100th value, rather than reaching 4million.
public class Improvement {
public static int Fibonacci(int j) {
/**
*
* Recursive took a long time so continued with iterative
*
* Complexity is n squared.. try to improve to just n
*
*/
int tmp;
int a = 2;
int b = 1;
int total = 0;
do {
if(isEven(a)) total +=a;
tmp = a + b;
b = a;
a = tmp;
} while (a < j);
return total;
}
private static boolean isEven(int a) {
return (a & 1) == 0;
}
public static void main(String[] args) {
// Notice there is no more loop here
System.out.println(Fibonacci(4_000_000));
}
}
Just to show the console from #mr1554 code answer, the first 100 even values are shown and then the sum of all is 4850741640 as can be seen below:
Any help is appreciated, thanks!
You need to use BigInteger because long easily overflows as Fibonacci's scales quite easily. BigInteger is also tricky to check whether is an odd or even number, but you can use BigInteger::testBit returning boolean as explained in this answer.
Here is some complete code:
BigInteger fibonacciSum(int count, boolean isOdd) {
int i = 0;
BigInteger sum = BigInteger.ZERO;
BigInteger current = BigInteger.ONE;
BigInteger next = BigInteger.ONE;
BigInteger temp;
while (i < count) {
temp = current;
current = current.add(next);
next = temp;
if ((current.testBit(0) && isOdd) || ((!current.testBit(0) && !isOdd))) {
sum = sum.add(current);
i++;
}
}
return sum;
}
Or you can have some fun with Stream API:
BigInteger fibonacciSum(int count, boolean isOdd) {
final BigInteger[] firstSecond = new BigInteger[] {BigInteger.ONE, BigInteger.ONE};
return Stream.iterate(
firstSecond,
num -> new BigInteger[] { num[1], num[0].add(num[1]) })
.filter(pair ->
(pair[1].testBit(0) && isOdd) ||
(!pair[1].testBit(0) && !isOdd))
.limit(count)
.map(pair -> pair[1])
.reduce(BigInteger.ZERO, BigInteger::add);
}
In any way, don't forget to test it out:
#Test
void test() {
assertThat(
fibonacciSum(100, false),
is(new BigInteger("290905784918002003245752779317049533129517076702883498623284700")));
}
You said.
My goal is to calculate the sum of the first 100 even-values Fibonacci numbers.
That number gets very large very quickly. You need to:
use BigInteger
use the mod function to determine if even
For this I could have started from (1,1) but it's only one term so ...
BigInteger m = BigInteger.ZERO;
BigInteger n = BigInteger.ONE;
BigInteger sumOfEven= BigInteger.ZERO;
int count = 0;
BigInteger t;
while( count < 100) {
t = n.add(m);
// check if even
if (t.mod(BigInteger.TWO).equals(BigInteger.ZERO)) {
sumOfEven = sumOfEven.add(t);
count++;
}
n = m;
m = t;
}
System.out.println(sumOfEven);
Prints
290905784918002003245752779317049533129517076702883498623284700
If, on the other hand, from your comment.
My aim is to calculate the sum of the first 100 even numbers
Then you can do that like so
sumFirstNeven = (((2N + 2)N)/2 = (N+1)N
so (101)100 = 10100 and the complexity is O(1)
as I figured, you want a program to sum 100 first even values of the Fibonacci series.
here is a sample code, when you run the program it will ask you to determine the number of the even values, you want 100 value e.g, type 100 in consul:
public static void main(String[] args) {
int firstNumber = 0;
int secondNumber = 2;
System.out.print("Enter the number of odd elements of the Fibonacci Series to sum : ");
Scanner scan = new Scanner(System.in);
int elementCount = scan.nextInt(); // number of even values you want
System.out.print(firstNumber + ", ");
System.out.print(secondNumber + ", ");
long sum = 2;
for (int i = 2; i < elementCount; i++) {
int nextNumber = firstNumber + secondNumber;
System.out.print(nextNumber + ", ");
sum += (nextNumber);
firstNumber = secondNumber;
secondNumber = nextNumber;
}
System.out.print("...");
System.out.println("\n" + "the sum of " + elementCount + " values of fibonacci series is: " + sum);
}

How do I write a superfactorial program?

Write a program to calculate and print the super factorial of a number using a for loop. The factorial of a number is the product of all integers up to and including that number, so the factorial of 4 (written as 4!) is 4*3*2*1= 24.
The super factorial is the product of all factorials up to and including that factorial.
4!!=4!*3!*2!*1!
I found "factorial" using the following code:
import java.util.Scanner;
public class superfactorial {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner input = new Scanner (System.in);
// number whose factorial to be found
int number;
// prompting input
System.out.print("Enter number: ");
number = input.nextInt();
int factorial = factorial(number);
System.out.printf("the factorial of %d is %d", number , factorial);
}
// method that calculates the factorial
public static int factorial (int n){
int output = 1;
for (int i=1; i <= n; i++) {
output = output * i;
}
return output;
}
}
Consider 4! = 4x3x2x1, you can see that there are 4 numbers in the decomposition. in general there will be n numbers in the decomposition of n! (n(n-1)(n-2)....(n-(n-1)). So all you need to do to get the super factorial is take the factorial of each component in the decomposition.
pseudo-code looks something like this
sp = 0
for i = n to 1:
sp = sp * factorial(i)
end for
return sp
The most important line in your factorial method is this line:
output = output * i;
You multiply output by i where i is an integer that keeps increasing by one.
What's the difference between a superfactorial and a normal factorial? To evaluate a superfactorial, you multiply output not by i, but by the factorial of i, right?
So just do it! I have already explained the whole thing to you! Just create a new method called superfactorial, copy all the stuff from the factorial method and change this line:
output = output * i;
to this:
output = output * factorial(i);
Here is a recursive approach.
Basically, in factorial you multiply n * fact(n-1). Here, we do fact(n) * superFact(n-1) as we need product of all factorials.
int superfactorial(int n) {
if (n == 0 || n == 1) {
return factorial(n);
} else {
return factorial(n) * superfactorial(n-1);
}
}
int factorial(int n) {
if(n == 0 || n == 1) {
return n;
} else {
return n * factorial(n-1);
}
}

Java Average Program

Write a class called Average that can be used to calculate average of several integers. It should contain the following methods:
A method that accepts two integer parameters and returns their average.
A method that accepts three integer parameters and returns their average.
A method that accepts two integer parameters that represent a range.
Issue an error message and return zero if the second parameter is less than the first one. Otherwise, the method should return the average of the integers in that range (inclusive).
Implement the class and write a program to test its methods and submit your source code (.java files).
I am stuck on part three, I don't even really understand the stipulation. Will I be using a floating point / double? Here is the program I have thus far:
import java.util.Scanner;
public class Average {
public static void main(String[] args) {
int numb1, numb2, numb3, userInput;
System.out.println("Enter '2' if you wish to average two numbers enter '3' if you wish to average 3.");
Scanner keyboard = new Scanner(System.in);
userInput = keyboard.nextInt();
if (userInput == 2){
System.out.println("Enter two numbers you'd like to be averaged.");
numb1 = keyboard.nextInt();
numb2 = keyboard.nextInt();
Average ave = new Average();
System.out.println("The average is: " + ave.average(numb1, numb2));
System.exit(1);
}
if(userInput == 3){
System.out.println("Enter three numbers you'd like to be averaged.");
numb1 = keyboard.nextInt();
numb2 = keyboard.nextInt();
numb3 = keyboard.nextInt();
Average ave = new Average();
System.out.println("The average is: " + ave.average(numb1, numb2, numb3));
System.exit(1);
}
}
public static int average (int num1, int num2) {
return (num1 + num2) / 2;
}
public static int average (int numb1, int numb2, int numb3){
return (numb1 + numb2 + numb3) / 3;
}
}
Please don't re-ask the same question as you just asked here: http://stackoverflow.com/questions/19507108/java-averaging-program
Rather update your other post to reflect your new code / questions.
Now onto your question:
A method that accepts two integer parameters that represent a range. Issue an error message and return zero if the second parameter is less than the first one. Otherwise, the method should return the average of the integers in that range (inclusive). Implement the class and write a program to test its methods and submit your source code (.java files).
Lets start by declaring our method and we'll declare it as static to conform to your program (since you're not creating your own objects). Then we want to check if the parameters follow the assignment instructions and return values accordingly.
public static int getRange(int firstValue, int secondValue)
{
int range;
if (firstValue > secondValue)
range = firstValue - secondValue;
else
{
range = 0;
System.out.println("Error!");
}
return range;
}
**To promote your understanding it's up to you to find the average of the integers in the range!
Not really here to do your homework, but since I'm already here, the range is the difference between the largest and smallest number.
public int returnRange(int first, int second) {
if(first > second)
return first-second;
else
return second-first;
}
To make things easier though...
public double returnAverage(int...numbers) {
for(int i = 0; i < numbers.length(); i++) {
total += numbers;
}
return total/numbers.length();
}
public int returnRange(int...numbers) {
int holder = 0;
int highest;
int lowest;
for(int i = 0; i < numbers.length(); i++) {
if(numbers[i] > holder) {
holder = numbers[i];
}
highest = holder;
for(int i = 0; i < numbers.length(); i++) {
if(numbers[i] < holder) {
holder = numbers[i];
}
}
lowest = holder;
return highest-lowest;
}
Last 2 methods are un-tested, but from experience, should work fine. These methods have arrays for the parameters, so you can do as many numbers as you'd like.
In your main method check for -1 and return error when first value is greater than second
public double avgRange(int a, int b){
if(a>b){
return -1;
}
else{
double total=0;
for(int x=a; x<=b; x++){
total = total + x;
}
return total/(b-a+1);
}
}
the method should return the average of the integers in that range (inclusive).
You're asked to return the average of all integers in the range bounded by the two parameters.
For example, if parameters were 5 and 10, the method should return the average of 5, 6, 7, 8, 9, and 10, which is 7.5. (5 and 10 are included because the question says the range should be "inclusive".)
To find the average, use a for loop to sum each integer in the range, then divide by the number of integers.
Will I be using a floating point / double?
The return value should be a float or double, since the average isn't always a whole number.

How to calculate the median of an array?

I'm trying to calculate the total, mean and median of an array thats populated by input received by a textfield. I've managed to work out the total and the mean, I just can't get the median to work. I think the array needs to be sorted before I can do this, but I'm not sure how to do this. Is this the problem, or is there another one that I didn't find? Here is my code:
import java.applet.Applet;
import java.awt.Graphics;
import java.awt.*;
import java.awt.event.*;
public class whileloopq extends Applet implements ActionListener
{
Label label;
TextField input;
int num;
int index;
int[] numArray = new int[20];
int sum;
int total;
double avg;
int median;
public void init ()
{
label = new Label("Enter numbers");
input = new TextField(5);
add(label);
add(input);
input.addActionListener(this);
index = 0;
}
public void actionPerformed (ActionEvent ev)
{
int num = Integer.parseInt(input.getText());
numArray[index] = num;
index++;
if (index == 20)
input.setEnabled(false);
input.setText("");
sum = 0;
for (int i = 0; i < numArray.length; i++)
{
sum += numArray[i];
}
total = sum;
avg = total / index;
median = numArray[numArray.length/2];
repaint();
}
public void paint (Graphics graf)
{
graf.drawString("Total = " + Integer.toString(total), 25, 85);
graf.drawString("Average = " + Double.toString(avg), 25, 100);
graf.drawString("Median = " + Integer.toString(median), 25, 115);
}
}
The Arrays class in Java has a static sort function, which you can invoke with Arrays.sort(numArray).
Arrays.sort(numArray);
double median;
if (numArray.length % 2 == 0)
median = ((double)numArray[numArray.length/2] + (double)numArray[numArray.length/2 - 1])/2;
else
median = (double) numArray[numArray.length/2];
Sorting the array is unnecessary and inefficient. There's a variation of the QuickSort (QuickSelect) algorithm which has an average run time of O(n); if you sort first, you're down to O(n log n). It actually finds the nth smallest item in a list; for a median, you just use n = half the list length. Let's call it quickNth (list, n).
The concept is that to find the nth smallest, choose a 'pivot' value. (Exactly how you choose it isn't critical; if you know the data will be thoroughly random, you can take the first item on the list.)
Split the original list into three smaller lists:
One with values smaller than the pivot.
One with values equal to the pivot.
And one with values greater than the pivot.
You then have three cases:
The "smaller" list has >= n items. In that case, you know that the nth smallest is in that list. Return quickNth(smaller, n).
The smaller list has < n items, but the sum of the lengths of the smaller and equal lists have >= n items. In this case, the nth is equal to any item in the "equal" list; you're done.
n is greater than the sum of the lengths of the smaller and equal lists. In that case, you can essentially skip over those two, and adjust n accordingly. Return quickNth(greater, n - length(smaller) - length(equal)).
Done.
If you're not sure that the data is thoroughly random, you need to be more sophisticated about choosing the pivot. Taking the median of the first value in the list, the last value in the list, and the one midway between the two works pretty well.
If you're very unlucky with your choice of pivots, and you always choose the smallest or highest value as your pivot, this takes O(n^2) time; that's bad. But, it's also very unlikely if you choose your pivot with a decent algorithm.
Sample code:
import java.util.*;
public class Utility {
/****************
* #param coll an ArrayList of Comparable objects
* #return the median of coll
*****************/
public static <T extends Number> double median(ArrayList<T> coll, Comparator<T> comp) {
double result;
int n = coll.size()/2;
if (coll.size() % 2 == 0) // even number of items; find the middle two and average them
result = (nth(coll, n-1, comp).doubleValue() + nth(coll, n, comp).doubleValue()) / 2.0;
else // odd number of items; return the one in the middle
result = nth(coll, n, comp).doubleValue();
return result;
} // median(coll)
/*****************
* #param coll a collection of Comparable objects
* #param n the position of the desired object, using the ordering defined on the list elements
* #return the nth smallest object
*******************/
public static <T> T nth(ArrayList<T> coll, int n, Comparator<T> comp) {
T result, pivot;
ArrayList<T> underPivot = new ArrayList<>(), overPivot = new ArrayList<>(), equalPivot = new ArrayList<>();
// choosing a pivot is a whole topic in itself.
// this implementation uses the simple strategy of grabbing something from the middle of the ArrayList.
pivot = coll.get(n/2);
// split coll into 3 lists based on comparison with the pivot
for (T obj : coll) {
int order = comp.compare(obj, pivot);
if (order < 0) // obj < pivot
underPivot.add(obj);
else if (order > 0) // obj > pivot
overPivot.add(obj);
else // obj = pivot
equalPivot.add(obj);
} // for each obj in coll
// recurse on the appropriate list
if (n < underPivot.size())
result = nth(underPivot, n, comp);
else if (n < underPivot.size() + equalPivot.size()) // equal to pivot; just return it
result = pivot;
else // everything in underPivot and equalPivot is too small. Adjust n accordingly in the recursion.
result = nth(overPivot, n - underPivot.size() - equalPivot.size(), comp);
return result;
} // nth(coll, n)
public static void main (String[] args) {
Comparator<Integer> comp = Comparator.naturalOrder();
Random rnd = new Random();
for (int size = 1; size <= 10; size++) {
ArrayList<Integer> coll = new ArrayList<>(size);
for (int i = 0; i < size; i++)
coll.add(rnd.nextInt(100));
System.out.println("Median of " + coll.toString() + " is " + median(coll, comp));
} // for a range of possible input sizes
} // main(args)
} // Utility
If you want to use any external library here is Apache commons math library using you can calculate the Median.
For more methods and use take look at the API documentation
import org.apache.commons.math3.*;
.....
......
........
//calculate median
public double getMedian(double[] values){
Median median = new Median();
double medianValue = median.evaluate(values);
return medianValue;
}
.......
For more on evaluate method AbstractUnivariateStatistic#evaluate
Update
Calculate in program
Generally, median is calculated using the following two formulas given here
If n is odd then Median (M) = value of ((n + 1)/2)th item term.
If n is even then Median (M) = value of [((n)/2)th item term + ((n)/2 + 1)th item term ]/2
In your program you have numArray, first you need to sort array using Arrays#sort
Arrays.sort(numArray);
int middle = numArray.length/2;
int medianValue = 0; //declare variable
if (numArray.length%2 == 1)
medianValue = numArray[middle];
else
medianValue = (numArray[middle-1] + numArray[middle]) / 2;
Arrays.sort(numArray);
return (numArray[size/2] + numArray[(size-1)/2]) / 2;
Arrays.sort(numArray);
int middle = ((numArray.length) / 2);
if(numArray.length % 2 == 0){
int medianA = numArray[middle];
int medianB = numArray[middle-1];
median = (medianA + medianB) / 2;
} else{
median = numArray[middle + 1];
}
EDIT: I initially had medianB setting to middle+1 in the even length arrays, this was wrong due to arrays starting count at 0. I have updated it to use middle-1 which is correct and should work properly for an array with an even length.
You can find good explanation at https://www.youtube.com/watch?time_continue=23&v=VmogG01IjYc
The idea it to use 2 Heaps viz one max heap and mean heap.
class Heap {
private Queue<Integer> low = new PriorityQueue<>(Comparator.reverseOrder());
private Queue<Integer> high = new PriorityQueue<>();
public void add(int number) {
Queue<Integer> target = low.size() <= high.size() ? low : high;
target.add(number);
balance();
}
private void balance() {
while(!low.isEmpty() && !high.isEmpty() && low.peek() > high.peek()) {
Integer lowHead= low.poll();
Integer highHead = high.poll();
low.add(highHead);
high.add(lowHead);
}
}
public double median() {
if(low.isEmpty() && high.isEmpty()) {
throw new IllegalStateException("Heap is empty");
} else {
return low.size() == high.size() ? (low.peek() + high.peek()) / 2.0 : low.peek();
}
}
}
Try sorting the array first. Then after it's sorted, if the array has an even amount of elements the mean of the middle two is the median, if it has a odd number, the middle element is the median.
Use Arrays.sort and then take the middle element (in case the number n of elements in the array is odd) or take the average of the two middle elements (in case n is even).
public static long median(long[] l)
{
Arrays.sort(l);
int middle = l.length / 2;
if (l.length % 2 == 0)
{
long left = l[middle - 1];
long right = l[middle];
return (left + right) / 2;
}
else
{
return l[middle];
}
}
Here are some examples:
#Test
public void evenTest()
{
long[] l = {
5, 6, 1, 3, 2
};
Assert.assertEquals((3 + 4) / 2, median(l));
}
#Test
public oddTest()
{
long[] l = {
5, 1, 3, 2, 4
};
Assert.assertEquals(3, median(l));
}
And in case your input is a Collection, you might use Google Guava to do something like this:
public static long median(Collection<Long> numbers)
{
return median(Longs.toArray(numbers)); // requires import com.google.common.primitives.Longs;
}
I was looking at the same statistics problems. The approach you are thinking it is good and it will work. (Answer to the sorting has been given)
But in case you are interested in algorithm performance, I think there are a couple of algorithms that have better performance than just sorting the array, one (QuickSelect) is indicated by #bruce-feist's answer and is very well explained.
[Java implementation: https://discuss.leetcode.com/topic/14611/java-quick-select ]
But there is a variation of this algorithm named median of medians, you can find a good explanation on this link:
http://austinrochford.com/posts/2013-10-28-median-of-medians.html
Java implementation of this:
- https://stackoverflow.com/a/27719796/957979
I faced a similar problem yesterday.
I wrote a method with Java generics in order to calculate the median value of every collection of Numbers; you can apply my method to collections of Doubles, Integers, Floats and returns a double. Please consider that my method creates another collection in order to not alter the original one.
I provide also a test, have fun. ;-)
public static <T extends Number & Comparable<T>> double median(Collection<T> numbers){
if(numbers.isEmpty()){
throw new IllegalArgumentException("Cannot compute median on empty collection of numbers");
}
List<T> numbersList = new ArrayList<>(numbers);
Collections.sort(numbersList);
int middle = numbersList.size()/2;
if(numbersList.size() % 2 == 0){
return 0.5 * (numbersList.get(middle).doubleValue() + numbersList.get(middle-1).doubleValue());
} else {
return numbersList.get(middle).doubleValue();
}
}
JUnit test code snippet:
/**
* Test of median method, of class Utils.
*/
#Test
public void testMedian() {
System.out.println("median");
Double expResult = 3.0;
Double result = Utils.median(Arrays.asList(3.0,2.0,1.0,9.0,13.0));
assertEquals(expResult, result);
expResult = 3.5;
result = Utils.median(Arrays.asList(3.0,2.0,1.0,9.0,4.0,13.0));
assertEquals(expResult, result);
}
Usage example (consider the class name is Utils):
List<Integer> intValues = ... //omitted init
Set<Float> floatValues = ... //omitted init
.....
double intListMedian = Utils.median(intValues);
double floatSetMedian = Utils.median(floatValues);
Note: my method works on collections, you can convert arrays of numbers to list of numbers as pointed here
And nobody paying attention when list contains only one element (list.size == 1). All your answers will crash with index out of bound exception, because integer division returns zero (1 / 2 = 0). Correct answer (in Kotlin):
MEDIAN("MEDIAN") {
override fun calculate(values: List<BigDecimal>): BigDecimal? {
if (values.size == 1) {
return values.first()
}
if (values.size > 1) {
val valuesSorted = values.sorted()
val mid = valuesSorted.size / 2
return if (valuesSorted.size % 2 != 0) {
valuesSorted[mid]
} else {
AVERAGE.calculate(listOf(valuesSorted[mid - 1], valuesSorted[mid]))
}
}
return null
}
},
As #Bruce-Feist mentions, for a large number of elements, I'd avoid any solution involving sort if performance is something you are concerned about. A different approach than those suggested in the other answers is Hoare's algorithm to find the k-th smallest of element of n items. This algorithm runs in O(n).
public int findKthSmallest(int[] array, int k)
{
if (array.length < 10)
{
Arrays.sort(array);
return array[k];
}
int start = 0;
int end = array.length - 1;
int x, temp;
int i, j;
while (start < end)
{
x = array[k];
i = start;
j = end;
do
{
while (array[i] < x)
i++;
while (x < array[j])
j--;
if (i <= j)
{
temp = array[i];
array[i] = array[j];
array[j] = temp;
i++;
j--;
}
} while (i <= j);
if (j < k)
start = i;
if (k < i)
end = j;
}
return array[k];
}
And to find the median:
public int median(int[] array)
{
int length = array.length;
if ((length & 1) == 0) // even
return (findKthSmallest(array, array.length / 2) + findKthSmallest(array, array.length / 2 + 1)) / 2;
else // odd
return findKthSmallest(array, array.length / 2);
}
public static int median(int[] arr) {
int median = 0;
java.util.Arrays.sort(arr);
for (int i=0;i<arr.length;i++) {
if (arr.length % 2 == 1) {
median = Math.round(arr[arr.length/2]);
} else {
median = (arr[(arr.length/2)] + arr[(arr.length/2)-1])/2;
}
}
return median;
}
Check out the Arrays.sort methods:
http://docs.oracle.com/javase/6/docs/api/java/util/Arrays.html
You should also really abstract finding the median into its own method, and just return the value to the calling method. This will make testing your code much easier.
public int[] data={31, 29, 47, 48, 23, 30, 21
, 40, 23, 39, 47, 47, 42, 44, 23, 26, 44, 32, 20, 40};
public double median()
{
Arrays.sort(this.data);
double result=0;
int size=this.data.length;
if(size%2==1)
{
result=data[((size-1)/2)+1];
System.out.println(" uneven size : "+result);
}
else
{
int middle_pair_first_index =(size-1)/2;
result=(data[middle_pair_first_index+1]+data[middle_pair_first_index])/2;
System.out.println(" Even size : "+result);
}
return result;
}
package arrays;
public class Arraymidleelement {
static public double middleArrayElement(int [] arr)
{
double mid;
if(arr.length%2==0)
{
mid=((double)arr[arr.length/2]+(double)arr[arr.length/2-1])/2;
return mid;
}
return arr[arr.length/2];
}
public static void main(String[] args) {
int arr[]= {1,2,3,4,5,6};
System.out.println( middleArrayElement(arr));
}
}

Java 2 array min max avg?

How do I create a loop to generate min, max, avg for 2 array lists, i have only generated the min, max and avg with sum for single array lists so far.
These are the 2 arrays User[] & Withdrawals[]:
User, Withdrawals
1 , 90.00
2 , 85.00
4 , 75.00
5 , 65.00
2 , 40.00
1 , 80.00
3 , 50.00
5 , 85.00
4 , 80.00
1 , 70.00
size = 10
This is what i have tried, as i have no clue about 2 arrays interdependent:
double min = 0.0;
double max = 0.0;
double sum = 0.0;
double avg = 0.0;
for(int i = 0; i <size; i++){
.
.
for(int j = 0; j < Withdrawals.length; j++){
if(Withdrawals[User[i]] > max){
max = Withdrawals[j];
}
if(Withdrawals[User[i]] < min){
min = Withdrawals[j];
}
}
sum += Withdrawals[j];
avg = sum/size;
}
how do i print the min, max, avg from the no of withdrawals per user ? :S
I have already counted the number of withdrawals per user.
Conditions are: create everything from scratch instead of using available library features of Java.
Divide and conquer :)
Yes, I know that is a term used for an algorithm technique, in this case what I mean is... work with small parts.
First having the min, max, avg for a simple array:
double[] values = {2,3,4,5,6,7};
double min = values[0];
double max = values[0];
double sum = 0;
for (double value : values) {
min = Math.min(value, min);
max = Math.max(value, max);
sum += value;
}
double avg = sum / values.length;
System.out.println("Min: " + min);
System.out.println("Max: " + max);
System.out.println("Avg: " + avg);
Note: Since you can't use Java libraries for your assignment, is easy to do your own versions of the min/max functions (read the Math JavaDoc)
Now you can encapsulate this code in a function, you can start by returning another array:
static double[] minMaxAvg(double[] values) {
double min = values[0];
double max = values[0];
double sum = 0;
for (double value : values) {
min = Math.min(value, min);
max = Math.max(value, max);
sum += value;
}
double avg = sum / values.length;
return new double[] {min, max, avg};
}
public static void main(String[] args) {
double[] values = {2,3,4,5,6,7};
double[] info = minMaxAvg(values);
System.out.println("Min: " + info[0]);
System.out.println("Max: " + info[1]);
System.out.println("Avg: " + info[2]);
}
Using an array is a little bit ugly to read, so is better if you create a class to hold the min, max, avg. So lets refactor the code a little bit:
class ValueSummary {
final double min;
final double max;
final double avg;
static ValueSummary createFor(double[] values) {
double min = values[0];
double max = values[0];
double sum = 0;
for (double value : values) {
min = Math.min(value, min);
max = Math.max(value, max);
sum += value;
}
double avg = sum / values.length;
return new ValueSummary(min, max, avg);
}
ValueSummary(double min, double max, double avg) {
this.min = min;
this.max = max;
this.avg = avg;
}
public String toString() {
return "Min: " + min + "\nMax: " + max +"\nAvg: " + avg;
}
}
public static void main(String[] args) {
double[] values = {2,3,4,5,6,7};
ValueSummary info = ValueSummary.createFor(values);
System.out.println(info);
}
You don't specify it in your question, but I assume that you have an array for each user (maybe each withdrawals is another array).
Now that you have the bottom parts, we can switch to a top-down thinking.
So your code could be something like this:
for (User aUser : users) {
System.out.println("User: " + aUser);
System.out.println(ValueSummary.createFor(withdrawalsOf(aUser)));
}
Ok, but this is just the idea, you still have the problem to relate aUser with its withdrawals. You have several options here:
Make a "table" User-> Withdrawals, that is what you are trying to do with the two arrays. The User index in the array acts like a "user id". When you learn about Map you will see that you can use a better representation for the index.
Having a Map or array is just an optimization, of the relationship User->Withdrawls, but you can represent that relationship with an object (ie UserWithdrawls)
Option 1:
static class User {
final String name;
public User(String s) { name = s; }
}
public static void main(String[] args) {
User[] users = { new User("John"), new User("Doe")};
double[][] withdrawals = {
new double[] { 1, 2, 3}, new double[] { 10,22, 30}
};
for (int i = 0; i < users.length; i++) {
System.out.println("User: " + users[i].name);
System.out.println(ValueSummary.createFor(withdrawals[i]));
}
}
Option 2:
static class User {
final String name;
public User(String s) { name = s; }
}
static class UserWithdrawls {
final User user;
final double[] withdrawals;
final ValueSummary summary;
UserWithdrawls(User user, double[] withdrawals) {
this.user = user;
this.withdrawals = withdrawals;
this.summary = ValueSummary.createFor(withdrawals);
}
}
public static void main(String[] args) {
UserWithdrawls[] userWithdrawls = {
new UserWithdrawls(new User("John"), new double[] { 1, 2, 3}),
new UserWithdrawls(new User("Doe"), new double[] { 10, 22, 30})
};
for (UserWithdrawls uw : userWithdrawls) {
System.out.println("User: " + uw.user.name);
System.out.println(uw.summary);
}
}
Additional notes: If you are studying Computer Science, you'll learn in the future that the loop to calculate max, min, avg has a complexity of O(n). If the values array is fully loaded in memory, doing the max/min/avg in three different functions (thus reading the array 3 times) is still an algorithm of O(n) order with a bigger constant. With the power of today's computers the constant is so small, that most of the time you'll not get any gain from calculating min/max/avg in the same loop. In contrast you can gain code readability, for example in Groovy the minMaxAvg code could be written like this:
def values = [2,3,4,5,6,7];
println values.min()
println values.max()
println values.sum() / values.size()
Quick n Dirty: Use a second for loop for the second array, but do not reinitialize the min, max etc again.
Cleaner would be to make a class to hold the min, max etc, and a method that is passed this result object and an array. The method then scans the array and updates the result objects min, max etc. Call the method for each array.
Why don't you try to look at the code of Descriptive Statistics in the Commons Math library? Or better, use it instead of reinvent the wheel?
DescriptiveStatistics de = new DescriptiveStatistics();
de.addValue(..) // Your values
// Add more values
Double max = de.getMax();
Double min = de.getMin();
Double avg = de.getSum() / de.getN(); // or de.getMean();
And use an instance of DescriptiveStatistics for every array.
I think it would be better if you stored the details for each user in a seperate data structure like the following class named UserWithdrawals.
public class Program1{
public static class UserWithdrawals{
private LinkedList<Double> withdrawals=new LinkedList<>();
public void add(Double amt){
this.withdrawals.add(amt);
}
public Double getMinimum(){
Double min=this.withdrawals.get(0);
for(Double amt:this.withdrawals)
if(amt.compareTo(min)<0) min=amt;
return min;
}
public Double getMaximum(){
Double max=this.withdrawals.get(0);
for(Double amt:this.withdrawals)
if(amt.compareTo(max)>0) max=amt;
return max;
}
public Double getAverage(){
Double sum=new Double(0);
for(Double amt:this.withdrawals)
sum+=amt;
return sum/this.withdrawals.size();
//this method will fail if the withdrawals list is updated during the iteration
}
/*You can also combine the three into a single method and return an array of Double object coz the iteration is same.*/
}
/*now you iterate over your two array lists (This wont work if the two array lists - 'Users' and 'Withdrawals' are of different size) and store the withdrawal data associated with a user in the corresponding map value - Maps or Associative arrays are a very basic data structure so your professor should not have any problems with this*/
private HashMap<Integer,UserWithdrawals> withdrawals_map=new HashMap<>();
public Program1(ArrayList<Integer> Users, ArrayList<Double> Withdrawals){
for(int i=0;i<Users.size();i++){
Integer user_no=Users.get(i);
Double withdrawal_amt=Withdrawals.get(i);
if(this.withdrawals_map.get(user_no)==null){
this.withdrawals_map.put(user_no,new UserWithdrawals());
}
this.withdrawals_map.get(user_no).add(withdrawal_amt);
}
}
public UserWithdrawals getUserWithdrawalsData(Integer user_no){
return this.withdrawals_map.get(user_no);
}
}
Sort the 2D array in O(log(n)) based on 1st column, by using c++ STL Sort function.
Traverse in O(n) to calculate the average and update MaxAverage.
// Driver function to sort the 2D vector
// on basis of a particular column
bool sortcol( const vector<int>& v1, const vector<int>& v2 ) {
return v1[0] < v2[0];
}
void sortMatrix()
{
// Initializing 2D vector "vect" with
// values S_ID,MARKS
vector< vector<int> > vect{{1,85}, {2,90}, {1,87}, {1,99}, {3,70}};
// Number of rows
int m = vect.size();
// Number of columns
int n = vect[0].size();
// Use of "sort()" for sorting on basis
// of 1st column
sort(vect.begin(), vect.end(),sortcol);
float maxAverage=-1;
int id=1; // assuming it starts from 1.
float sum=0;
int s=0; // size of marks per student to calculate average
for( int i=0; i<m; i++ )
{
sum+=vect[i][1];
s=s+1;
if( i+1!= m && vect[i+1][0] != vect[i][0] ){// gotten all the marks of this student
maxAverage = maxAverage>sum/s? maxAverage:sum/s;
id = vect[i][0];
s=0;
sum=0;
}
}
cout<<"ID: "<<id<<"\tValue: "<<maxAverage<<endl;
}
Output:
ID: 2 Value: 90.3333

Categories

Resources