我需要帮助解决这个问题,我需要一个 3x5 的数组,然后当用户选择一个位置时,输出将显示相邻数字的最小值。像这样:
3 5 6 7 8
6 7 8 2 3
0 9 2 1 1
用户选择位置1,1。//对角线也算在内。
输出:周围的最小值为0。
这是我的代码,问题是我问是否有比到处乱发 if 和 else 更好的方法。
private static int checkAdjacentField(int p1, int p2, int[][] ae) {
int min = Integer.MAX_VALUE;
if (p1 == 0) {
if (p2 == 0) {
if (ae[p1][p2+1] < min) {
min = ae[p1][p2+1];
} else if (ae[p1+1][p2+1] < min) {
min = ae[p1+1][p2+1];
} else if (ae[p1+1][p2] < min) {
min = ae[p1+1][p2];
}
} else if (p2 == 1) {
if (ae[p1][p2+1] < min){
min = ae[p1][p2+1];
} else if (ae[p1+1][p2+1] < min) {
min = ae[p1+1][p2+1];
} else if (ae[p1+1][p2] < min) {
min = ae[p1+1][p2];
} else if (ae[p1+1][p2-1] < min) {
min = ae[p1+1][p2-1];
} else if (ae[p1][p2-1] < min) {
min = ae[p1][p2-1];
}
}
}
return min;
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
Random r = new Random();
int [][] ar = new int[3][5];
for (int i = 0; i < ar.length; i++) {
System.out.println();
for (int j = 0; j < 5; j++) {
int rand = r.nextInt(9) + 1;
ar[i][j]=rand;
System.out.printf("%3d",ar[i][j]);
}
}
System.out.println();
System.out.println("Select a position [][]: ");
int pos1 = Integer.parseInt(br.readLine());
int pos2 = Integer.parseInt(br.readLine());
System.out.println("The min value around is " + checkAdjacentField(pos1,pos2,ar));
}
}
在代码中,0,0 和 0,1 有效,是的,我可以花时间做 if else 的垃圾邮件方法,但我想知道是否有更好的方法,以便我可以改进。感谢您的帮助,欢迎任何想法或答案。
最佳答案
我认为最好的方法是使用以下算法:
- 所有相邻位置的列表(无论它们是否在数组中)
- 过滤掉不在数组中的
- 将剩余位置映射到数组中的值
- 查找最小的一个(因为我们处理的是整数,您可以对它们进行排序并取第一个)
这样:
private static int checkAdjacentField(int col, int row, int[][] ae) {
int nbRows = ae.length;
int nbCols = ae[0].length;
// Stream all the 8 positions around your position
Stream<Point> positions = Stream.of(
new Point(col-1, row-1), new Point(col-1, row), new Point(col-1, row+1),
new Point(col, row-1), new Point(col, row+1),
new Point(col+1, row-1), new Point(col+1, row), new Point(col+1, row+1));
return positions
.filter(p -> p.x>=0 && p.y>=0 && p.x<nbCols && p.y<nbRows) // keep those inbound
.mapToInt(p -> ae[p.y][p.x]) // replace positions by their values in the array
.sorted() // sort the values
.findFirst().orElse(-1); // take the first one (smallest)
}
您甚至可以生成点列表,而不是对它们进行硬编码
private static int checkAdjacentField(int col, int row, int[][] ae) {
int nbRows = ae.length;
int nbCols = ae[0].length;
// Stream all the 8 positions around your position
Stream<Point> positions = IntStream.rangeClosed(-1, 1).boxed() // -1, 0, 1
.map(c -> IntStream.rangeClosed(-1, 1).boxed() // -1, 0, 1
.map(r -> new Point(col+c, row+r)))
.flatMap(p -> p) // to a list
.filter(p -> !(p.x == col && p.y==row)); // remove center point
// then same as first example
return positions
.filter(p -> p.x>=0 && p.y>=0 && p.x<nbCols && p.y<nbRows)
.mapToInt(p -> ae[p.y][p.x])
.sorted()
.findFirst().orElse(-1);
}
我更喜欢像第一个示例一样对它们进行硬编码,这样更清晰。
关于java - 相邻数组的最小值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59323787/