我需要在删除第一个值后确定最小值。
例如,这些是数字0.5 70 80 90 10
我需要删除0.5,确定剩余数字中的最小值。 calweightAvg是我的重点......
最终输出应该是“当使用数据0.5 70 80 90 10时,数字的加权平均值是40,其中0.5是权重,并且在丢弃其余值的最低值之后计算平均值。 “
编辑:除了最终的输出外,一切似乎都在起作用。 "当使用数据70.0,80.0,90.0,10.0时,数字的加权平均值是40.0,其中 70.0 (应该是0.5)是权重,并且在下降后计算平均值剩下的价值中最低的。"所以数学是正确的,输出不是。
编辑:使用类static double weight=0.5;
来确定权重时,如果用户要更改输入文件中的值,那将无效。我怎样才能改变班级?
/*
*
*/
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();
}
}
答案 0 :(得分:2)
以复杂的O(n)来完成这项任务并不是一项艰巨的任务。
您可以使用ArrayList
&#39; s .get(0)
在temp变量中保存权重,然后使用.remove(0)
函数删除第一个值(在本例中为0.5)
然后你应该使用For Each循环for (Double d : list)
求和并找到最小值
然后从总和中减去最小值。并将权重应用于总和(在这种情况下,您最终会得到240 * 0.5 = 120; 120 \ 3 = 40;
最后,您可以使用ArrayList
&#39; .size()
- 1函数来确定除数。
代码中的问题:
return (sum-min)/(inputValues.size()-1) * inputValues.get(0);
((70+80+90+10)-10)/(4-1) * (70) = 5600
if(inputValues.size() <= 1){ inputValues.remove(0); }
>=1
需要在抽象代码中采取的完整步骤:
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!
请注意,现在可以通过ArrayList
的{{1}}功能安全地将重量添加回数组列表中。此外,代码非常抽象,应该实施有关大小的保护措施。
关于您的修改:
您似乎正在输出错误的变量。
out.print(&#34; \ n其中&#34; + inputValues.get(0)+&#34;是重量,&#34;);
此阶段已经从列表中删除了权重变量,因此列表中的第一项确实是70.要么在计算结果后将权重变量添加回列表,要么将其保存在类变量并直接输入。
以下是两种解决方案的实施。你应该只使用其中一个而不是两个。
1)将重量添加回列表解决方案:
更改此功能以将重量添加回列表:
.add(int index, T value)
2)类变量解决方案:
班级变更:
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.
double returnVal = (sum-min)/(inputValues.size()-1) * weight;
// add weight back to list
inputValues.add(0,weight);
return returnVal;
}
更改功能:
public class CalcWeightedAvg {
static double weight=0;
//...
}
更改输出:
public static double calcWeightedAvg(ArrayList<Double> inputValues){
//Get and remove weight.
weight = inputValues.get(0); // changed to class variable
//...
}
答案 1 :(得分:0)
如果你想删除ArrayList
中的第一个元素并计算剩下的最小元素,你应该这样做:
if(inputValues.size() <= 1) //no point in calculation of one element
return;
inputValues.remove(0);
double min = inputValues.get(0);
for (int i = 1; i < inputValues.size(); i++) {
if (inputValues.get(i) < min)
min = inputValues.get(i);
}
答案 2 :(得分:0)
由于你正在使用ArrayList,这应该是件小事。
要从ArrayList中删除值,只需找到值的索引并调用
myList.remove(index);
如果0.5是列表中的第一个元素,请使用
将其删除inputValues.remove(0);
如果要在双精度数组列表中找到最小值,只需使用此算法查找最小值及其索引:
double minVal = Double.MAX_VALUE;
int minIndex = -1;
for(int i = 0; i < myList.size(); i++) {
if(myList.get(i) < minVal) {
minVal = myList.get(i);
minIndex = i;
}
}
希望这有帮助!
答案 3 :(得分:0)
我对你的目标有点不清楚。如果您需要频繁调用以检查最小值,那么最小堆将是一个非常好的选择。
min heap具有以下属性:它提供对最小值的恒定时间访问。此[implementation]使用ArrayList。因此,您可以使用add()
方法添加到ArrayList,minValue()
可以持续访问列表的最小值,因为它可以确保最小值始终为索引0.列表为在删除最小值或添加新值(称为heapify)时相应地进行修改。
我不在这里添加任何代码,因为链接应该使该部分清楚。如果您想要一些澄清,我会非常乐意帮助您。
修改强>
public class HelloWorld {
private static ArrayList<Double> values;
private static Double sum = 0.0D;
/**
* Identifies the minimum value stored in the heap
* @return the minimum value
*/
public static Double minValue() {
if (values.size() == 0) {
throw new NoSuchElementException();
}
return values.get(0);
}
/**
* Adds a new value to the heap.
* @param newValue the value to be added
*/
public static void add(Double newValue) {
values.add(newValue);
int pos = values.size()-1;
while (pos > 0) {
if (newValue.compareTo(values.get((pos-1)/2)) < 0) {
values.set(pos, values.get((pos-1)/2));
pos = (pos-1)/2;
}
else {
break;
}
}
values.set(pos, newValue);
// update global sum
sum += newValue;
}
/**
* Removes the minimum value from the heap.
*/
public static void remove() {
Double newValue = values.remove(values.size()-1);
int pos = 0;
if (values.size() > 0) {
while (2*pos+1 < values.size()) {
int minChild = 2*pos+1;
if (2*pos+2 < values.size() &&
values.get(2*pos+2).compareTo(values.get(2*pos+1)) < 0) {
minChild = 2*pos+2;
}
if (newValue.compareTo(values.get(minChild)) > 0) {
values.set(pos, values.get(minChild));
pos = minChild;
}
else {
break;
}
}
values.set(pos, newValue);
}
// update global sum
sum -= newValue;
}
/**
* NEEDS EDIT Computes the average of the list, leaving out the minimum value.
* @param newValue the value to be added
*/
public static double calcWeightedAvg() {
double minValue = minValue();
// the running total of the sum took this into account
// so, we have to remove this from the sum to get the effective sum
double effectiveSum = (sum - minValue);
return effectiveSum * minValue;
}
public static void main(String []args) {
values = new ArrayList<Double>();
// add values to the arraylist -> order is intentionally ruined
double[] arr = new double[]{10,70,90,80,0.5};
for(double val: arr)
add(val);
System.out.println("Present minimum in the list: " + minValue()); // 0.5
System.out.println("CalcWeightedAvg: " + calcWeightedAvg()); // 125.0
}
}