怎样判断类围棋中的联通区域(图已经加上) 如上图右边所示,上面分别有标记r和g的区域,只有红色的r和黄色的g的区域才叫做最大的联通区域。比如这个棋盘叫做a,那秒a[1][0]和a[1][1]也是r联通区域,只不过没有哪个红色的r联通区域大,但是我的问题是,我不知道怎样去判断这样的联通区域,需要去储存还是怎样?一点思路没有。希望大家给点意见,实在没想法。这个背景是做一个minmax树做剪枝算法。可是苦于无法判断联通区域,所有程序都搁置在这了谢谢大家 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 我算法学的不好。。不知道你是不是要这种抛个砖。。public static void main(String[] args) throws IOException { char[][] array = { {'r', 'g', 'r', 'g'}, {'r', 'r', 'r', 'r'}, {'g', 'r', 'g', 'r'}, {'g', 'g', 'g', 'g'} }; boolean[][] explored = new boolean[4][4]; List<Point> list = explore('r', array, explored, 0, 0); for(Point p : list){ System.out.println(p.x + "," + p.y); } } //探索从x,y点发散开与targetChar相同的点 private static List<Point> explore(char targetChar,char[][] array, boolean[][] explored, int x, int y){ //此点下表越界,直接返回null if(x < 0 || y < 0 || y >= array.length || x >= array[y].length) return null; //如果此点已经被探索过,或者与目标不同,直接返回null if(explored[y][x] || array[y][x] != targetChar) return null; //记录此点已被探索过 explored[y][x] = true; //将此点加入到list List<Point> pointList = new ArrayList<Point>(); pointList.add(new Point(x, y)); //取出周围所有点的坐标 Point[] aroundPoints = { new Point(x, y - 1), new Point(x, y + 1), new Point(x - 1, y), new Point(x + 1, y) }; //递归获取周围与周围所有联通点连接的点 for(Point point : aroundPoints){ List<Point> list = explore(targetChar, array, explored, point.x, point.y); if(list != null) pointList.addAll(list); } return pointList; } 多谢仁兄代码相赠啊~ 你程序是做判断联通区域的,得到的肯定是一片联通区域。但是我现在的麻烦是怎样得到一片最大的联通区域,可能就是说,多建立几个点的联通区域,比较得出最大然后取出最大list数目那个即可。但是在哪里建立基本点(就是基于这个点做联通区域求解)是个问题,这个棋盘只是4×4的,如果要是10×10的棋盘,那采点的标准就成了问题,不知道在哪里采点是最有效的(有效到能把所有联通区域囊括其中。)因为这个背景是要面临组合爆炸问题,所以要进行剪枝,如果搜索联通区域的任务占用了很多时间,那剪枝算法就效率大减。现在我是一点头绪没有。不过谢谢你的代码,写的很漂亮。 棋盘上只有 r 和 g 两种区域吗?enum Realm { R, G;}public Set<Point> getMaxRealm(Realm[][] board, Realm r); // any board[i][j] != null是这个意思吗? 遍历 +1import java.awt.Point;import java.util.Collections;import java.util.Comparator;import java.util.HashMap;import java.util.HashSet;import java.util.Map;import java.util.Set;import java.util.TreeSet;/** * * @date 23/10/2012 */public enum Realm { R, G; public static void main(String[] args) { Realm[][] board1 = { { R, G, R, G }, { R, R, R, R }, { G, R, G, R }, { G, G, G, G } }; Realm[][] board2 = { { G, G, R, R }, { R, R, G, G }, { G, G, G, R }, { R, G, R, R } }; Map<Set<Point>, Realm> realms1 = getAllRealms(board1); for(Set<Point> points : realms1.keySet()) System.out.println(realms1.get(points) + " - " + points); System.out.println("\n------\n"); Map<Set<Point>, Realm> realms2 = getAllRealms(board2); for(Set<Point> points : realms2.keySet()) System.out.println(realms2.get(points) + " - " + points); } public static Map<Set<Point>, Realm> getAllRealms(Realm[][] board) { // check parameters if( board == null ) throw new NullPointerException(); if( board.length == 0 ) return Collections.emptyMap(); int height = board.length; int width = board[0].length; for(Realm[] row : board) { if( row.length != width ) throw new IllegalArgumentException(); for(Realm p : row) if( p == null ) throw new NullPointerException(); } if( width == 0 ) return Collections.emptyMap(); // do the work Set<Point> visited = new HashSet<Point>(width * height); Map<Set<Point>, Realm> result = new HashMap<Set<Point>, Realm>(); for(Point p = new Point(0, 0); p.y < height; p = nextPoint(width, p)) { if( visited.contains(p) ) continue; Realm r = board[p.y][p.x]; Set<Point> current = new TreeSet<Point>(PointComparator.INSTANCE); collect(current, board, p, r); visited.addAll(current); result.put(current, r); } return result; } private static void collect(Set<Point> set, Realm[][] board, Point p, Realm r) { if( set.contains(p) ) return; if( p.y < 0 || p.y >= board.length ) return; if( p.x < 0 || p.x >= board[0].length ) return; if( board[p.y][p.x] != r ) return; set.add(p); for(Direction d : Direction.values()) collect(set, board, d.of(p), r); } private static Point nextPoint(int width, Point p) { p = Direction.Right.of(p); if( p.x >= width ) { p.x = 0; Direction.Down.move(p); } return p; }}enum PointComparator implements Comparator<Point> { INSTANCE; @Override public int compare(Point o1, Point o2) { int result = o1.y - o2.y; return result == 0 ? o1.x - o2.x : result; }}enum Direction { Up { @Override void move(Point p) { --p.y; } }, Left { @Override void move(Point p) { --p.x; } }, Right { @Override void move(Point p) { ++p.x; } }, Down { @Override void move(Point p) { ++p.y; } },; Point of(Point p) { Point result = new Point(p); move(result); return result; } abstract void move(Point p);}////run://R - [java.awt.Point[x=0,y=0], java.awt.Point[x=2,y=0], java.awt.Point[x=0,y=1], java.awt.Point[x=1,y=1], java.awt.Point[x=2,y=1], java.awt.Point[x=3,y=1], java.awt.Point[x=1,y=2], java.awt.Point[x=3,y=2]]//G - [java.awt.Point[x=3,y=0]]//G - [java.awt.Point[x=1,y=0]]//G - [java.awt.Point[x=0,y=2], java.awt.Point[x=2,y=2], java.awt.Point[x=0,y=3], java.awt.Point[x=1,y=3], java.awt.Point[x=2,y=3], java.awt.Point[x=3,y=3]]////------////R - [java.awt.Point[x=0,y=3]]//R - [java.awt.Point[x=3,y=2], java.awt.Point[x=2,y=3], java.awt.Point[x=3,y=3]]//R - [java.awt.Point[x=0,y=1], java.awt.Point[x=1,y=1]]//R - [java.awt.Point[x=2,y=0], java.awt.Point[x=3,y=0]]//G - [java.awt.Point[x=0,y=0], java.awt.Point[x=1,y=0]]//G - [java.awt.Point[x=2,y=1], java.awt.Point[x=3,y=1], java.awt.Point[x=0,y=2], java.awt.Point[x=1,y=2], java.awt.Point[x=2,y=2], java.awt.Point[x=1,y=3]]//BUILD SUCCESSFUL (total time: 0 seconds) java中vector问题 请教 正则表达式 求救:急!!! Unable to instantiate default tuplizer 试问我这样的需求反射可以满足吗? java 怎么调用 vf数据库文件 高手近来看看,关于javaGUI的窗口总在最前问题 怎样在程序中编写窗口事件? jdbc运行问题 关于 if(true) 与 Unreachable code double类型取余 图片blob转成了String,如何将String转成图片文件保存?
抛个砖。。public static void main(String[] args) throws IOException {
char[][] array = {
{'r', 'g', 'r', 'g'},
{'r', 'r', 'r', 'r'},
{'g', 'r', 'g', 'r'},
{'g', 'g', 'g', 'g'}
};
boolean[][] explored = new boolean[4][4];
List<Point> list = explore('r', array, explored, 0, 0);
for(Point p : list){
System.out.println(p.x + "," + p.y);
}
}
//探索从x,y点发散开与targetChar相同的点
private static List<Point> explore(char targetChar,char[][] array, boolean[][] explored, int x, int y){
//此点下表越界,直接返回null
if(x < 0 || y < 0 || y >= array.length || x >= array[y].length)
return null;
//如果此点已经被探索过,或者与目标不同,直接返回null
if(explored[y][x] || array[y][x] != targetChar)
return null;
//记录此点已被探索过
explored[y][x] = true;
//将此点加入到list
List<Point> pointList = new ArrayList<Point>();
pointList.add(new Point(x, y));
//取出周围所有点的坐标
Point[] aroundPoints = {
new Point(x, y - 1),
new Point(x, y + 1),
new Point(x - 1, y),
new Point(x + 1, y)
};
//递归获取周围与周围所有联通点连接的点
for(Point point : aroundPoints){
List<Point> list = explore(targetChar, array, explored, point.x, point.y);
if(list != null)
pointList.addAll(list);
}
return pointList;
}
但是我现在的麻烦是怎样得到一片最大的联通区域,可能就是说,多建立几个点的联通区域,比较得出最大然后取出最大list数目那个即可。
但是在哪里建立基本点(就是基于这个点做联通区域求解)是个问题,这个棋盘只是4×4的,如果要是10×10的棋盘,那采点的标准就成了问题,不知道在哪里采点是最有效的(有效到能把所有联通区域囊括其中。)
因为这个背景是要面临组合爆炸问题,所以要进行剪枝,如果搜索联通区域的任务占用了很多时间,那剪枝算法就效率大减。现在我是一点头绪没有。
不过谢谢你的代码,写的很漂亮。
enum Realm {
R, G;
}public Set<Point> getMaxRealm(Realm[][] board, Realm r); // any board[i][j] != null
是这个意思吗?
import java.awt.Point;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;/**
*
* @date 23/10/2012
*/
public enum Realm { R,
G;
public static void main(String[] args) {
Realm[][] board1 = {
{ R, G, R, G },
{ R, R, R, R },
{ G, R, G, R },
{ G, G, G, G }
};
Realm[][] board2 = {
{ G, G, R, R },
{ R, R, G, G },
{ G, G, G, R },
{ R, G, R, R }
};
Map<Set<Point>, Realm> realms1 = getAllRealms(board1);
for(Set<Point> points : realms1.keySet())
System.out.println(realms1.get(points) + " - " + points);
System.out.println("\n------\n");
Map<Set<Point>, Realm> realms2 = getAllRealms(board2);
for(Set<Point> points : realms2.keySet())
System.out.println(realms2.get(points) + " - " + points);
} public static Map<Set<Point>, Realm> getAllRealms(Realm[][] board) { // check parameters
if( board == null )
throw new NullPointerException(); if( board.length == 0 )
return Collections.emptyMap(); int height = board.length;
int width = board[0].length; for(Realm[] row : board) { if( row.length != width )
throw new IllegalArgumentException(); for(Realm p : row)
if( p == null )
throw new NullPointerException();
} if( width == 0 )
return Collections.emptyMap(); // do the work
Set<Point> visited = new HashSet<Point>(width * height);
Map<Set<Point>, Realm> result = new HashMap<Set<Point>, Realm>(); for(Point p = new Point(0, 0); p.y < height; p = nextPoint(width, p)) {
if( visited.contains(p) )
continue;
Realm r = board[p.y][p.x];
Set<Point> current = new TreeSet<Point>(PointComparator.INSTANCE);
collect(current, board, p, r);
visited.addAll(current);
result.put(current, r);
}
return result;
}
private static void collect(Set<Point> set, Realm[][] board, Point p, Realm r) {
if( set.contains(p) )
return;
if( p.y < 0 || p.y >= board.length )
return;
if( p.x < 0 || p.x >= board[0].length )
return;
if( board[p.y][p.x] != r )
return;
set.add(p);
for(Direction d : Direction.values())
collect(set, board, d.of(p), r);
} private static Point nextPoint(int width, Point p) { p = Direction.Right.of(p);
if( p.x >= width ) {
p.x = 0;
Direction.Down.move(p);
}
return p;
}
}enum PointComparator implements Comparator<Point> { INSTANCE; @Override
public int compare(Point o1, Point o2) { int result = o1.y - o2.y;
return result == 0 ? o1.x - o2.x : result;
}
}enum Direction { Up { @Override
void move(Point p) {
--p.y;
}
},
Left { @Override
void move(Point p) { --p.x;
}
},
Right { @Override
void move(Point p) { ++p.x;
}
},
Down { @Override
void move(Point p) {
++p.y;
}
},; Point of(Point p) { Point result = new Point(p);
move(result);
return result;
} abstract void move(Point p);
}//
//run:
//R - [java.awt.Point[x=0,y=0], java.awt.Point[x=2,y=0], java.awt.Point[x=0,y=1], java.awt.Point[x=1,y=1], java.awt.Point[x=2,y=1], java.awt.Point[x=3,y=1], java.awt.Point[x=1,y=2], java.awt.Point[x=3,y=2]]
//G - [java.awt.Point[x=3,y=0]]
//G - [java.awt.Point[x=1,y=0]]
//G - [java.awt.Point[x=0,y=2], java.awt.Point[x=2,y=2], java.awt.Point[x=0,y=3], java.awt.Point[x=1,y=3], java.awt.Point[x=2,y=3], java.awt.Point[x=3,y=3]]
//
//------
//
//R - [java.awt.Point[x=0,y=3]]
//R - [java.awt.Point[x=3,y=2], java.awt.Point[x=2,y=3], java.awt.Point[x=3,y=3]]
//R - [java.awt.Point[x=0,y=1], java.awt.Point[x=1,y=1]]
//R - [java.awt.Point[x=2,y=0], java.awt.Point[x=3,y=0]]
//G - [java.awt.Point[x=0,y=0], java.awt.Point[x=1,y=0]]
//G - [java.awt.Point[x=2,y=1], java.awt.Point[x=3,y=1], java.awt.Point[x=0,y=2], java.awt.Point[x=1,y=2], java.awt.Point[x=2,y=2], java.awt.Point[x=1,y=3]]
//BUILD SUCCESSFUL (total time: 0 seconds)