【问题标题】:I'm trying to understand how to work with 2D arrays我正在尝试了解如何使用 2D 数组
【发布时间】:2021-04-26 17:25:56
【问题描述】:

我有一个 CSV 文件,其中包含近 65,000 行,分为 3 个值(经度、纬度和高度)。我要做的是创建一个经纬度的数组[][]。经度和纬度是双精度数,它们不能用于索引,但不知道如何将它们映射到索引。所以我想它会是这样的:

array[0][0] = altitude_value[0];
array[0][1] = altitude_value[1];
            ·
            ·
            ·
array[i][j] = altitude_value[z];

值如下:

-179.75,-89.75,-1965
-179.75,-89.5,-2011
-179.75,-89.25,-2140
-179.75,-89,-2162

我试图根据以下方法获得的经度和纬度参数来获得高度:

public double getAltitude(double longitude, double latitude) {
    return array[array.indexOf(longitude)][array.indexOf(latitude)] = altitude_value;
}

【问题讨论】:

  • 为什么要在 get 方法中设置值?删除= altitude_value 部分
  • 不相关,但如果有任何重复的纬度/经度值,它可能无法满足您的需求。
  • @azro 这是一种假设的方法,但我正在尝试以类似的方式实现数组
  • @DaveNewton 有很多重复项,为什么不起作用?
  • 您可能需要考虑在此处使用Map 而不是数组。

标签: java arrays multidimensional-array


【解决方案1】:

如果你坚持使用二维数组,你可以像这样映射你的值:

array[0][0] = longitude[0];
array[0][1] = latitude[0];
array[0][2] = altitude[0];
array[1][0] = longitude[1];
array[1][1] = latitude[1];
array[1][2] = altitude[1];
...
array[n][0] = longitude[n];
array[n][1] = latitude[n];
array[n][2] = altitude[n];

更好的解决方案是创建一个Position 类来保存一个经度、纬度和高度。然后你可以拥有一个由Position 实例组成的一维数组。

编辑添加:

这是一个简单的例子。我用你的四个位置线作为输入。

-179.75,-89.75,-1965
-179.75,-89.5,-2011
-179.75,-89.25,-2140
-179.75,-89,-2162

我收到以下经度 -179.75,纬度 -89.5 的输出。

-2011

我在创建的一维数组中使用了简单的线性搜索。对于 4 个值,它足够快。对于 65,000 个值,您可以运行我的代码并查看需要多长时间。正如我所说,如果您按经度、纬度对数组进行排序并使用二进制搜索,您将在大约 32 次测试中得到正确的结果。

这是我使用的完整可运行代码。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class PositionApp {

    public static void main(String[] args) {
        new PositionApp().run();
    }
    
    private Position[] positions;
    
    public void run() {
        try {
            int count = readCSVFile();
            this.positions = new Position[count];
            processCSVFile();
            int altitude = getAltitude(-179.75, -89.5);
            System.out.println(altitude);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    public int readCSVFile() throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(
                getClass().getResourceAsStream("/sample.csv")));
        int count = 0;
        String line = reader.readLine();
        while (line != null) {
            count++;
            line = reader.readLine();
        }
        reader.close();
        return count;
    }
    
    public void processCSVFile() throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(
                getClass().getResourceAsStream("/sample.csv")));
        int count = 0;
        String line = reader.readLine();
        while (line != null) {
            String[] parts = line.split(",");
            double longitude = Double.valueOf(parts[0]);
            double latitude = Double.valueOf(parts[1]);
            int altitude = Integer.valueOf(parts[2]);
            positions[count++] = new Position(longitude, latitude, altitude);
            line = reader.readLine();
        }
        reader.close();
    }
    
    public int getAltitude(double longitude, double latitude) {
        for (int index = 0; index < positions.length; index++) {
            if ((positions[index].getLongitude() == longitude) &&
                (positions[index].getLatitude() == latitude)) {
                return positions[index].getAltitude();
            }
        }
        return Integer.MIN_VALUE;
    }
    
    public class Position {
        
        private final int altitude;
        
        private final double longitude;
        private final double latitude;
        
        public Position(double longitude, double latitude, int altitude) {
            this.longitude = longitude;
            this.latitude = latitude;
            this.altitude = altitude;
        }

        public int getAltitude() {
            return altitude;
        }

        public double getLongitude() {
            return longitude;
        }

        public double getLatitude() {
            return latitude;
        }
        
    }

}

【讨论】:

  • 我认为 OP 实际上想构建一个从纬度/经度对到高度值的地图,而不是将它们全部存储在一个数组中。
  • @HenryTwist:是的,但是 OP 说他不允许使用地图。创建数组后,可以对其进行排序并通过二分搜索找到高度。
  • @GilbertLeBlanc 你能帮我做吗?你会使用 for 循环吗?
【解决方案2】:

为了简单起见,假设您的经度和纬度从 0 到 1,增量为 0.25(n = 5 增量)。然后您的映射将如下所示:

0, 0 -> a0
0, 0.25 -> a1
...
0.25, 0 -> a5
...

然后您可以使用由[longitude * 4][latitude * 4] 确定的索引[x][y] 访问任何经度和纬度值的高度。

显然,对于您的实际示例,您需要在查询数组时将经度和纬度值偏移为零,但这不应该是太多额外的工作。

【讨论】:

    【解决方案3】:

    Java 原始数组没有“indexOf”方法,例如您提供的 getAltitude 方法中所示的方法。您需要将其转换为 List 或使用诸如 java.util.Array 之类的辅助类来获得该功能。

    看看如何尝试使用数组索引,使用另一种数据类型可能会更好,例如 Map of Maps。这些其他数据类型的基本功能在概念上与 2D 数组相同,但与原始数组相比,它允许更多种类的索引数据类型。

    使用 Map of Maps 的基本实现:

    
        Map<Double, Map<Double,Double> longitudeMap; //Read your CSV file into this data structure
    
        public double getAltitude(double longitude, double latitude) {
        
            Map<Double> latitudeMap = longitudeMap.get(longitude);
            double altitude = latitudeMap.get(latitude);
        
            return altitude;
        }
    

    这可以使用链式获取简化为更少的行。它还需要一些 NULL 保护,但应该传达基于 Map 的解决方案的要点,而不是原始数组解决方案。

    如果您必须使用经度和纬度索引的原始数组,您基本上是在手动构建映射(什么值映射到数据数组中的什么索引)并且需要存储该索引在一个单独的对象中,它可以是一个数组,但最好作为一个列表。您在 getAltitude 中的“indexOf”将进入您的索引对象,而不是数据数组。

    【讨论】:

      猜你喜欢
      • 2022-01-13
      • 2017-12-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多