元素到达列表的末尾

时间:2014-12-28 03:07:11

标签: java list

所以,伙计们。我对Java(以及其他任何编程语言)都很陌生,而且我在处理列表时遇到了一些麻烦。我已经编写了这段代码,以便集成一个函数,给定低级和高级限制,以及调步。虽然,我注意到,对于不同于1的调步,列表(list_x)会搞砸,并且值会直接到达它的末尾。 以下是完整的代码:

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Integrate {
    static List<Double> fillx(double ini,double end, double pace) { //Fills the x column
        List<Double> list_x = new ArrayList<Double>();
        for(double i = ini; i <= (end+0.1*pace); i += pace) {
           int i2 = (int) ((i-ini)/pace);
           list_x.add(i2, i);
        }
        System.out.println(list_x);
        return list_x;
    }
    static List<List<Double>> filly(List<Double> listx){ //Fills the y column
        List<List<Double>> listxy= new ArrayList<List<Double>>();
        for(int i = 0; i < listx.size();i++) {
            List<Double> pair = new ArrayList<Double>();
            pair.add(0,listx.get(i));
            pair.add(1,function(listx.get(i)));
            listxy.add(i,pair);
            System.out.println(pair);
        }
        return listxy;
    }
    static double function(double x) { //Defines the function to be integrated
    return x;
    }
    static double integrate(List<List<Double>> listxy) { //Integrates following trapezoidal forms
        double area = 0;
        for(int i=0; (i+1) < listxy.size();i++) {
           area += 0.5*(listxy.get(i+1).get(0)-listxy.get(i).get(0))*      (listxy.get(i+1).get(1)+listxy.get(i).get(1));
           System.out.println(listxy.get(i+1).get(0)+" "+listxy.get(i).get(0)+" "+listxy.get(i+1).get(1)+" "+listxy.get(i).get(1));
        }
        return area;
    }
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        double ini = scan.nextDouble(); //Reads the inferior limit
        double end = scan.nextDouble(); //Reads the superior limit
        double pace = scan.nextDouble(); //Reads the pace (partial to be summed).
        if (((end-ini) % pace) < pace) {
        System.out.println(integrate(filly(fillx(ini,end,pace))));}
        else
            System.out.println("Must review pace");
   }
}

我得到了这些结果(值为ini = 0,end = 1,pace = 1E-1

[0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.6, 0.7, 0.7999999999999999, 0.8999999999999999, 0.9999999999999999, 0.5]

如果你还有其他任何评论,我会很高兴的。由于我自己学习,所有的帮助都是受欢迎的。

1 个答案:

答案 0 :(得分:0)

构造list_x时,会发生以下情况:

adding 0.0 at index 0    [0.0]
...
adding 0.5 at index 5    [0,0, 0.1,... 0.5]
adding 0.6 at index 5     Bang: [0,0, 0.1,... 0.6, 0.5]
adding 0.7 at index 6    [0,0, 0.1,... 0.6, 0.7, 0.5]

你看到这是如何将0.5推到最后。

你正在做所谓的“过度工程”:害怕做得不够,做得太多。

// The List is perfectly capable of appending at the end, which is exactly what you want:
for(double i = ini; i <= (end+0.1*pace); i += pace) {
    list_x.add(i);
}

还有很多需要说的。我将添加一些评论 - 坚持下去。

脚注1 双重算术

int i2 = (int) ((i-ini)/pace);

此类计算存在风险。除法可能导致一个值或略高于整数,然后转换为int截断并产生您期望的值。但是,它可能会稍微返回一个双倍(请参见那些0.x999999999999999),然后截断结果会比您预期的少一个。

int i2 = (int)Math.round((i-ini)/pace);

脚注2 计算一系列双打

不是将double重复添加到另一个double,而是直接计算。 (我还添加了ini,以获得正确的横坐标值。)

int n = (int)Math.round((end - ini)/pace) + 1;
    for(int i = 0; i < n; ++i) {
    list_x.add(ini + i*pace);
}

Footnode 3 使用适当的课程

两个列表不是存储一对坐标的好方法。可以定义一个简单的类Point:

public class Point {
    private double x;
    private double y;
    Point( double x, double y ){
        this.x = x;
        this.y = y;
    }
    public double getX(){
        return x;
    }
    public double getY(){
        return y;
    }
    public String toString(){
        return "<" + x + "," + y + ">";
    }
}

现在,x-y组合可以像这样计算:

static List<Point> fillp(List<Double> listx){
    List<Point> listp = new ArrayList<>();
    for(int i = 0; i < listx.size(); i++) {
    Point p = new Point( listx.get(i), function(listx.get(i)) );
        listp.add( p );
    }
    return listp;
}

脚注4 为什么列出所有这些?

无需存储可轻松计算的值或仅计算一次的值。只需动态计算它们即可。这简化了您的代码:

public class Trapez {
    static double function(double x) { //Defines the function to be integrated
        return x;
    }

    static double trapezoidalRule( double a, double b, double h ){
        int n = (int)Math.round((b - a)/h) + 1;
        double area = 0;
        double y = function( a );
        for( int i = 1; i < n; i++ ){
            double y1 = function( a + h*i );
            area += 0.5*h*(y + y1);
            y = y1;
        }
        return area;
    }

    public static void main(String[] args) {
        System.out.println( trapezoidalRule( 0, 1, 0.1 ) );
    }
}

结论传递函数的更好方法是什么?

Java 8具有函数形式(lambdas)。在简单的情况下,它们易于使用,我在删除方法function时结束了我的讨论。 (我使用f(x)= 2x使函数定义与参数不同。)

import java.util.function.Function;
public class Trapez {
    static double trapezoidalRule( Function<Double,Double> f, double a, double b, double h ){
        int n = (int)Math.round((b - a)/h) + 1;
        double area = 0;
        double y = f.apply( a );
        for( int i = 1; i < n; i++ ){
            double y1 = f.apply( a + h*i );
            area += 0.5*h*(y + y1);
            y = y1;
        }
        return area;
    }
    public static void main(String[] args) {
        System.out.println( trapezoidalRule( x -> 2*x, 0, 1, 0.1 ) );
    }
}