如何删除值,确定剩余值的最小值

时间:2016-04-17 03:26:42

标签: java for-loop arraylist netbeans

我需要在删除第一个值后确定最小值。

例如,这些是数字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();
}

}

4 个答案:

答案 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
  • 即使这是你的意图,在大小== 0 \ 1 \ 2的边缘情况下,这也不会导致算法的正确计算。我建议你重新考虑一下。

需要在抽象代码中采取的完整步骤:

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
    }
}