搜索数组

时间:2014-03-28 22:14:00

标签: java arrays

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

我知道如何通过编写8 if循环来实现它,并且对于每个if循环我需要确保它不受限制。我觉得这种方法非常低效和低劣。任何人都可以启发我的创意方法吗?

3 个答案:

答案 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的方法。

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