2014-03-28 83 views
0

假设我有一个随机填充1和2的6乘6 int数组。我想打印出现在特定点(x,y)附近的1的数量。在数组中搜索

我知道如何通过编写8 if循环和每个if循环来做到这一点,我需要确保它不会出界。我觉得这种方法效率极低,效率低下。任何人都可以启发我一个创造性的方法?

+3

8如果循环?不,你只需要2个循环与一个条件检查 –

回答

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-束缚是多么小,最大将使其以最低0(这同样适用于上限,但在反向)

+0

我不明白。 – user3443299

+0

你有两个for循环。将编辑以使答案更清晰 –

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

} 

} 
0

这是一种利用Java8 Streams/Predicates的方法。

  • 开始与X,Y
  • 生成围绕中心测试点的列表 - 使用预定义的BOX
  • 应用谓词函数来验证该点你想测试是在你的网格范围内。
  • 如果是这样,请获取该位置的值并测试它是否为1 [或在此应用任何谓词]。

通过定义前期的代码静态逻辑实际上只是归结为

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,2,2] ,2,1,2]
Point = [2,2]
结果=
[1,1]
[1,2]
[1,3]
[2,3]
[3,1]
[3,2]