Tôi có một trò chơi mô phỏng thành phố và cố gắng tìm một cách để kiểm tra dòng chảy của hệ thống điện của chúng tôi. Thông tin cơ bản: Bản đồ cho thành phố dựa trên các ô (30 x 30 gạch = 900 ô). Bây giờ tôi bắt đầu tại một nhà máy điện và thực hiện kiểm tra hàng xóm đệ quy (trên cùng, bên trái, bên phải, phía dưới) để kiểm tra xem có cái gì đó sẽ vận chuyển sức mạnh không. Nếu có cái gì đó, tôi cũng bắt đầu kiểm tra gạch này cho hàng xóm. Để ngăn chặn kiểm tra đôi và/hoặc cuộc gọi đệ quy vô hạn, tôi điền vào một ArrayList với gạch xử lý và kiểm tra xem một ngói mới đã được xử lý và thêm vào ArrayList ...đệ quy + 900 yếu tố + hàng xóm kiểm tra = nguyên nhân stackoverflow
đệ quy bắt đầu:
public void updatePowerEnvironment(int id, ArrayList<Integer> elements) {
Log.w("GT", "update env for id: " + id);
int newId = id - GameMap.mMapSize;
if (newId >= 0 && GameMap.mMapCells.get(newId).mPowerEnabled
&& !elements.contains(newId)) {
elements.add(newId);
updatePowerEnvironment(newId, elements);
}
newId = id + GameMap.mMapSize;
if (newId < GameMap.mMapCells.size() && GameMap.mMapCells.get(newId).mPowerEnabled
&& !elements.contains(newId)) {
elements.add(newId);
updatePowerEnvironment(newId, elements);
}
newId = id - 1;
if (newId >= 0 && GameMap.mMapCells.get(newId).mPowerEnabled
&& !elements.contains(newId)) {
elements.add(newId);
updatePowerEnvironment(newId, elements);
}
newId = id + 1;
if (newId < GameMap.mMapCells.size()
&& GameMap.mMapCells.get(newId).mPowerEnabled
&& !elements.contains(newId)) {
elements.add(newId);
updatePowerEnvironment(newId, elements);
}
}
Nếu tôi có thể tin tưởng đầu ra nhật ký, không có lát nào được xử lý hai lần. Điều đó có nghĩa, rằng tôi không có lỗi trong các cuộc gọi đệ quy. Điều này cũng có nghĩa là, ngăn xếp chỉ đơn giản là quá nhỏ.
Có ai đó có ý tưởng cách tránh giới hạn ngăn xếp không?
[Update và mã của tôi là kết quả của Erics câu trả lời]
public void updatePowerEnvironment(int id, ArrayList<Integer> elements) {
Stack<Integer> toProcess = new Stack<Integer>();
toProcess.push(id);
int mapSize = GameMap.mMapCells.size();
while (!toProcess.empty()) {
id = toProcess.pop();
Log.e("GT", "id to process: " + id);
if (elements.contains(id)) {
continue;
}
int[] neighborIds = computeNeighbors(id);
for (int neighbor : neighborIds) {
if (neighbor < 0 || neighbor >= mapSize) {
continue;
}
if (!GameMap.mMapCells.get(neighbor).mPowerEnabled) {
continue;
}
toProcess.push(neighbor);
}
elements.add(id);
}
}
private int[] computeNeighbors(int id) {
return new int[] {id + GameMap.mMapSize, id - GameMap.mMapSize, id + 1, id - 1};
}
Tôi không thấy một trường hợp cơ sở ở đây ... – NullUserException
@NullUserException: Trường hợp cơ sở là "nếu không có gạch trợ chưa qua chế biến theo hướng nào sau đó không làm gì cả". Bạn không nhìn thấy nó bởi vì không có mã cần thiết để thực hiện "không làm gì". –
FWIW, bạn có thể thiết lập kích thước của ngăn xếp của một chủ đề một cách rõ ràng khi tạo ra nó (xem các nhà thầu đề). Như những người khác đã lưu ý, đó không phải là giải pháp đúng, nhưng tôi nghĩ rằng tôi muốn đề cập đến nó cho đầy đủ. – fadden