假设我有一个随机填充1和2的6乘6的int数组。我想打印在特定点(x,y)附近出现的1的数量。
我知道如何通过编写8 if循环来实现它,并且对于每个if循环我需要确保它不受限制。我觉得这种方法非常低效和低劣。任何人都可以启发我的创意方法吗?
答案 0 :(得分:1)
Jigar Joshi建议的两个循环解决方案可能是最佳的。你只需要一个循环从max(0,x-bound)开始,以min(5,x + bound)结束,另一个从max(0,y-bound)开始,以min(5,y + bound)结束)。
编辑:一些有助于理解的代码
for(int i = Math.max(0, x-bound); i<Math.min(5, x+bound); i++){
for(int j = Math.max(0, y-bound); j<Math.min(5, y+bound); j++){
//Your check/counter here
}
}
max和min函数用于检查边界。简单地说,无论x-bound多么小,max都会使它达到最小值0.(同样适用于上限但反过来)
答案 1 :(得分:0)
这是我的“创意方法”: - )
public class CountOnes {
int[][] space = new int[8][8]; //Notice this is 8x8 instead of 6x6
public CountOnes() {
//Adding value 100 all around the 6x6 array
for (int i = 0; i < 8; i++) {
space[0][i] = 100;
space[i][0] = 100;
space[i][7] = 100;
space[7][i] = 100;
}
}
/**
* Just print out the matrix
*/
public void showSpace() {
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
System.out.print("[" + space[i][j] + "]");
}
System.out.println();
}
}
/**
*
* @param x horizontal position in range [0-5]
* @param y vertical position in range [0-5]
* @param val 1 or 2
*/
public void insertValueAt(int x, int y, int val) {
//Should throw an exception if val != 1 and val != 2 or x and y are out of bounds [0 - 5]
space[x + 1][y + 1] = val; //Convert coordinates before inserting in 8x8 matrix
}
public int numberOfOnesAroundPosition(int x, int y) {
//Should throw exception if x and y are out of bounds [0 - 5]
int tot = 0;
//add up all values around (x,y)
for (int i = -1; i < 2; i++) {
for (int j = -1; j < 2; j++) {
tot += space[x + 1 + i][y + 1 + j];//convert coordinates adding 1 because we are in 8x8
}
}
tot -= space[x + 1][y + 1];//remove value of (x,y) because it was added in previous loop
return 2 * (8 - (tot / 100)) - (tot % 100); //the formula
}
/**
* @param args
*/
public static void main(String[] args) {
//simple test case
CountOnes count = new CountOnes();
for (int i = 0; i < 6; i++) {
for (int j = 0; j < 6; j++) {
count.insertValueAt(i, j, 1);
}
}
count.insertValueAt(2, 2, 2);
count.showSpace();
for (int i = 0; i < 6; i++) {
for (int j = 0; j < 6; j++) {
System.out.println("[" + i + "," + j + "] => "
+ count.numberOfOnesAroundPosition(i, j));
}
}
}
}
答案 2 :(得分:0)
这是一种利用Java8 Streams / Predicates的方法。
通过预先定义静态逻辑,代码实际上只归结为
Stream<Point> results=
BOX.stream()
.map(p -> Point.of(p.X + centerPoint.X, p.Y + centerPoint.Y))
.filter(p -> inBounds.test(p) && a6x6.get(p.X).get(p.Y) == 1);
我确信在Java7中可以使用更多的函数来应用相同的逻辑,您可以将它用于任何网格大小。
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.function.Predicate;
import java.util.stream.Stream;
public class Main {
public static class Point {
public final Integer X;
public final Integer Y;
public Point(Integer X, Integer Y){
this.X = X;
this.Y = Y;
}
public static Point of(Integer x, Integer y){
return new Point(x,y);
}
@Override
public String toString() {
return String.format("[%s,%s]", X, Y);
}
}
//Bounds of grid
private static final Point MIN = Point.of(0,0);
private static final Point MAX = Point.of(5,5);
/**
* [-1,-1][-1,0][-1,1]
* [ 0,-1][ _,_][ 0,1]
* [ 1,-1][ 1,0][ 1,1]
**/
private static final List<Point> BOX = new ArrayList<Point>(){{
add(Point.of(-1,-1));
add(Point.of(-1,0));
add(Point.of(-1,1));
add(Point.of(0,-1));
add(Point.of(0,1));
add(Point.of(1,-1));
add(Point.of(1,0));
add(Point.of(1,1));
}};
public static final Predicate<Point> inBounds =
p -> {
if (p.X < MIN.X || p.Y < MIN.Y) return false;
if (p.X > MAX.X || p.Y > MAX.Y) return false;
return true;
};
public static void main(String[] args) {
final Random rand = new Random();
final List<List<Integer>> a6x6 = new ArrayList<List<Integer>>(){{
for(int i=0;i<6;i++)
add(new ArrayList<Integer>(){{
for(int i=0;i<6;i++)
add(rand.nextInt(2) + 1);
}});
}};
final Point centerPoint = Point.of(2,2);
System.out.println("Grid = ");
a6x6.forEach(System.out::println);
System.out.println("Point = " + centerPoint.toString());
Stream<Point> results=
BOX.stream()
.map(p -> Point.of(p.X + centerPoint.X, p.Y + centerPoint.Y))
.filter(p -> inBounds.test(p) && a6x6.get(p.X).get(p.Y) == 1);
System.out.println("Results = ");
results.forEach(System.out::println);
}
}
结果:
网格=
[2,2,1,2,1,1]
[1,1,1,1,1,2]
[1,2,1,1,2,1]
[2,1,1,2,1,2]
[1,1,1,1,1,1]
[1,2,2,2,1,2]
点= [2,2]
结果=
[1,1]
[1,2]
[1,3]
[2,3]
[3,1]
并[3,2]