我必须做一个用随机(0到2)数字填充二维数组的算法,唯一的条件是我可以在水平和垂直方向上使用相同的数字3次或更多次。 例如
[0,0,1,2,1
0,1,2,1,2
1,2,0,1,0]
没问题
[0,0,0,2,1
0,1,2,1,2
1,2,0,1,0]
或
[0,0,1,2,1
0,1,1,1,2
1,2,1,1,0]
错了。
所以这是我的算法:
public class CandyHelper {
private final int minimumChainLength = 3;
private final int searchChainSize = 3;
public Candy[][] randomInit(int rowCount, int columnCount) {
Candy[][] map = new Candy[rowCount][columnCount];
for (int row = 0; row < rowCount; ++row) {
for (int column = 0; column < columnCount; ++column) {
// Fill square with random candy.
Random rand = new Random();
int value = rand.nextInt(3);
Candy candy = new Candy();
candy.setType(value);
map[row][column] = candy;
}
}
if (findHint(map)) {
//System.out.println("Winning conditions");
map = null;
map = randomInit(rowCount, columnCount);
} else {
System.out.println("no wining");
}
return map;
}
// Function which searches for match of at least `MinimumChainLength`.
private boolean findHint(Candy[][] map) {
int rowCount = map.length;
int columnCount = map.length;
List<Candy> hintMove = new ArrayList<Candy>();
// Search rows.
for (int row = 0; row < rowCount; ++row) {
// Search for chain.
for (int chainStart = 0; chainStart < columnCount - searchChainSize; ++chainStart) {
// Add initial cell in chain.
hintMove.clear();
hintMove.add(map[row][chainStart]);
for (int nextInChain = chainStart + 1; nextInChain < columnCount; ++nextInChain) {
if (map[row][nextInChain].getType() == hintMove.get(0).getType()) {
hintMove.add(map[row][nextInChain]);
} else {
break;
}
}
// Was a chain found?
if (hintMove.size() >= minimumChainLength)
return true;
}
}
// Search columns.
for (int column = 0; column < columnCount; ++column) {
// Search for chain.
for (int chainStart = 0; chainStart < rowCount - searchChainSize; ++chainStart) {
// Add initial cell in chain.
hintMove.clear();
hintMove.add(map[chainStart][column]);
for (int nextInChain = chainStart + 1; nextInChain < rowCount; ++nextInChain) {
if (map[nextInChain][column].getType() == hintMove.get(0).getType()) {
hintMove.add(map[nextInChain][column]);
} else {
break;
}
}
// Was a chain found?
if (hintMove.size() >= minimumChainLength)
return true;
}
}
// No chain was found, so clear hint.
hintMove.clear();
return false;
}
}
和我的pojo:
public class Candy {
private int type;
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
@Override
public String toString() {
return "Candy{" + "type=" + type + '}';
}
}
当我从10x10的数组开始时,我开始收到堆栈溢出错误。 我该怎么做才能纠正它们?
提前致谢。
答案 0 :(得分:1)
你的问题就在这一行:
map = randomInit(rowCount, columnCount);
基本上每次findHint返回true时,你都会以递归方式调用randomInit。这意味着FindHint返回true的概率越大,堆栈溢出的可能性就越大。在你的情况下,你的网格越大,FindHint返回true的概率就越高,我猜大小10几乎肯定会在堆栈溢出中结束。
我很诚实我不知道为什么你在这里再次调用randomInit而不是仅仅返回地图?
答案 1 :(得分:0)
如果randomInit()
为真,我会猜测它与findHint()
调用自身有关。我发现findHint()
的代码没有任何问题(除了一些性能调整 - 例如,你没有必要构建一个匹配列表来计算有多少匹配),但事实上你可能只是在10x10网格上遇到这个问题。任何只有三种类型的10x10对象网格很可能连续三个 - 这可能会导致你的randomInit()
自行调用足够的时间来让你的堆栈溢出。
我不是100%确定你想要randomInit()
做什么。如果你希望它在没有N组的情况下继续生成随机网格,我建议将网格生成代码放在一个单独的方法中(称之为generate()
),然后让randomInit()
调用它一个循环:
boolean setFound;
do {
map = generate(rowCount, columnCount);
setFound = findHint(map);
} while (setFound);