javafordummies - 1 year ago 80

Java Question

I need to determine the minimum value after removing the first value.

For instance is these are the numbers 0.5 70 80 90 10

I need to remove 0.5, the determine the minimum value in the remaining numbers. calweightAvg is my focus ...

The final output should be “The weighted average of the numbers is 40, when using the data 0.5 70 80 90 10, where 0.5 is the weight, and the average is computed after dropping the lowest of the rest of the values.”

EDIT: Everything seems to be working, EXCEPT during the final out put. "The weighted average of the numbers is 40.0, when using the data 70.0, 80.0, 90.0, 10.0, where **70.0** (should be 0.5) is the weight, and the average is computed after dropping the lowest of the rest of the values."

So the math is right, the output is not.

`/*`

*

*/

package calcweightedavg;

import java.util.Scanner;

import java.util.ArrayList;

import java.io.File;

import java.io.PrintWriter;

import java.io.FileNotFoundException;

import java.io.IOException;

public class CalcWeightedAvg {

/**

* @param args the command line arguments

*/

public static void main(String[] args) throws IOException {

//System.out.println(System.getProperty("user.dir"));

ArrayList<Double> inputValues = getData(); // User entered integers.

double weightedAvg = calcWeightedAvg(inputValues); // User entered weight.

printResults(inputValues, weightedAvg); //Weighted average of integers.

}

public class CalcWeightedAvg {

/**

* @param args the command line arguments

*/

public static void main(String[] args) throws IOException {

//System.out.println(System.getProperty("user.dir"));

ArrayList<Double> inputValues = getData(); // User entered integers.

double weightedAvg = calcWeightedAvg(inputValues); // User entered weight.

printResults(inputValues, weightedAvg); //Weighted average of integers.

}

public static ArrayList<Double> getData() throws FileNotFoundException {

// Get input file name.

Scanner console = new Scanner(System.in);

System.out.print("Input File: ");

String inputFileName = console.next();

File inputFile = new File(inputFileName);

//

Scanner in = new Scanner(inputFile);

String inputString = in.nextLine();

//

String[] strArray = inputString.split("\\s+"); //LEFT OFF HERE

// Create arraylist with integers.

ArrayList<Double> doubleArrayList = new ArrayList<>();

for (String strElement : strArray) {

doubleArrayList.add(Double.parseDouble(strElement));

}

in.close();

return doubleArrayList;

}

public static double calcWeightedAvg(ArrayList<Double> inputValues){

//Get and remove weight.

Double weight = inputValues.get(0);

inputValues.remove(0);

//Sum and find min.

double min = Double.MAX_VALUE;

double sum = 0;

for (Double d : inputValues) {

if (d < min) min = d;

sum += d;

}

// Calculate weighted average.

return (sum-min)/(inputValues.size()-1) * weight;

}

public static void printResults(ArrayList<Double> inputValues, double weightedAvg) throws IOException {

Scanner console = new Scanner(System.in);

System.out.print("Output File: ");

String outputFileName = console.next();

PrintWriter out = new PrintWriter(outputFileName);

System.out.println("Your output is in the file " + outputFileName);

out.print("The weighted average of the numbers is " + weightedAvg + ", ");

out.print("when using the data ");

for (int i=0; i<inputValues.size(); i++) {

out.print(inputValues.get(i) + ", ");

}

out.print("\n where " + inputValues.get(0) + " is the weight, ");

out.print("and the average is computed after dropping the lowest of the rest of the values.\n");

out.close();

}

}

Answer

to do this task in a complexity of O(n) isn't a hard task.
you can use `ArrayList`

's `.get(0)`

to Save weight in a temp variable, then use `.remove(0)`

function which removes the first value (in this case 0.5)

then you should use a For Each loop `for (Double d : list)`

to sum AND find the minimal value

afterwards subtract the minimum value from the sum. and apply weight to the sum (in this case you'll end up with 240*0.5 = 120; 120\3 = 40;

finally, you can use `ArrayList`

's `.size()`

-1 function to determine the divisor.

**The problem in your code:**

- in your implementation you've removed the weight item from list. then multiplied by the first item in the list even though it's no longer the weight:

`return (sum-min)/(inputValues.size()-1) * inputValues.get(0);`

- your calculation than was:
`((70+80+90+10)-10)/(4-1) * (70) = 5600`

`if(inputValues.size() <= 1){ inputValues.remove(0); }`

- this size safeguard will not remove weight from the list. perhaps you've meant to use
`>=1`

- even if that was your intention this will not result in a correct computation of your algorithm in the edge cases where size==0\1\2 I would recommend that you re-think this.

**the full steps that need to be taken in abstract code:**

```
ArrayList<Double> list = new ArrayList();
// get and remove weight
Double weight = list.get(0);
list.remove(0);
// sum and find min
double min=Double.MAX_VALUE;
double sum=0;
for (Double d : list) {
if (d<min) min = d;
sum+=d;
}
// subtract min value from sum
sum-=min;
// apply weight
sum*=weight;
// calc weighted avg
double avg = sum/list.size()-1;
// viola!
```

do take notice that you can now safely add weight back into the array list after its use via `ArrayList`

's `.add(int index, T value)`

function. also, the code is very abstract and safeguards regarding size should be implemented.

**Regarding your Edit:**

it appears you're outputting the wrong variable.

out.print("\n where " + inputValues.get(0) + " is the weight, ");

the weight variable was already removed from the list at this stage, so the first item in the list is indeed 70. either add back the weight variable into the list after you've computed the result or save it in a class variable and input it directly.

change for class:

```
public class CalcWeightedAvg {
static double weight=0;
//...
}
```

change for function:

```
public static double calcWeightedAvg(ArrayList<Double> inputValues){
//Get and remove weight.
weight = inputValues.get(0); // changed to class variable
//...
}
```