Untitled
Anonymous
java
02/16/2026 2:18 AM
8.1 KB
11
Indexable
import java.util.*;
public class GameOfLifeFile {
// ==================== Mock File System ====================
private static Map<String, String> filesystem = new HashMap<>();
static String read(String name, int offset, int length) {
String content = filesystem.getOrDefault(name, "");
return content.substring(offset, Math.min(offset + length, content.length()));
}
static void append(String name, String contents) {
filesystem.merge(name, contents, String::concat);
}
// ==================== File Helpers ====================
private static String rowFileName(int gen, int row) {
return "gen" + gen + "_row" + row;
}
/**
* 把一行 int[] 写入文件,每个 cell 用 '0' 或 '1' 表示
*/
private static void writeRow(int gen, int row, int[] data) {
StringBuilder sb = new StringBuilder(data.length);
for (int val : data) {
sb.append(val);
}
append(rowFileName(gen, row), sb.toString());
}
/**
* 从文件读取一行,返回 int[]
*/
private static int[] readRow(int gen, int row, int cols) {
String content = read(rowFileName(gen, row), 0, cols);
int[] result = new int[cols];
for (int j = 0; j < cols; j++) {
result[j] = content.charAt(j) - '0';
}
return result;
}
// ==================== Initialize ====================
public static void initialize(int[][] board) {
for (int i = 0; i < board.length; i++) {
writeRow(0, i, board[i]);
}
}
// ==================== 核心:基于 3 行滑动窗口的 nextGen ====================
/**
* 用滑动窗口处理,内存中只保留 3 行。
* 复用原题代码的计数逻辑:遍历周围 8 个方向,统计活邻居数。
*
* rows[0] = 上一行 (i-1),可能为 null
* rows[1] = 当前行 (i)
* rows[2] = 下一行 (i+1),可能为 null
*/
private static int[] processRow(int[] prevRow, int[] currRow, int[] nextRow, int cols) {
// 把 3 行组装成一个小的局部 board,方便复用原始代码的双重循环逻辑
// 局部 board: 最多 3 行,当前行始终在 index = localI
// prevRow 存在 → localBoard[0], currRow → localBoard[1], nextRow → localBoard[2]
// prevRow 不存在 → currRow → localBoard[0], nextRow → localBoard[1]
// 但这样映射比较麻烦,不如直接用数组引用更清晰:
int[] newRow = new int[cols];
for (int j = 0; j < cols; j++) {
int count = 0;
// 遍历 3 行 × 3 列 的邻域,和原始代码思路完全一致
// rows 数组: index 0 = prevRow, 1 = currRow, 2 = nextRow
// dx 对应: -1, 0, +1
int[][] rows = {prevRow, currRow, nextRow};
for (int dx = -1; dx <= 1; dx++) {
for (int dy = -1; dy <= 1; dy++) {
// 跳过自身
if (dx == 0 && dy == 0) continue;
int rowIdx = 1 + dx; // dx=-1 → rows[0]=prevRow, dx=0 → rows[1]=currRow, dx=1 → rows[2]=nextRow
int nj = j + dy;
// 边界检查:行越界(prevRow/nextRow 为 null)或列越界
if (rows[rowIdx] == null) continue;
if (nj < 0 || nj >= cols) continue;
// 统计活细胞(直接读文件的原始值,不存在中间状态,所以 ==1 即可)
if (rows[rowIdx][nj] == 1) count++;
}
}
// 和原始代码一样的规则判断
if (currRow[j] == 1 && (count < 2 || count > 3)) {
newRow[j] = 0; // 活 → 死
} else if (currRow[j] == 0 && count == 3) {
newRow[j] = 1; // 死 → 活
} else {
newRow[j] = currRow[j]; // 保持不变
}
}
return newRow;
}
/**
* 计算下一代。从 gen 读,写入 gen+1。
* 内存开销:O(cols),只保留 3 行。
*/
public static void nextGen(int gen, int m, int n) {
int[] prevRow = null;
int[] currRow = readRow(gen, 0, n);
int[] nextRow = (m > 1) ? readRow(gen, 1, n) : null;
for (int i = 0; i < m; i++) {
// 处理当前行
int[] newRow = processRow(prevRow, currRow, nextRow, n);
writeRow(gen + 1, i, newRow);
// 滑动窗口:向下移一行
prevRow = currRow;
currRow = nextRow;
nextRow = (i + 2 < m) ? readRow(gen, i + 2, n) : null;
}
}
// ==================== 读取结果 ====================
public static int[][] readBoard(int gen, int m, int n) {
int[][] board = new int[m][n];
for (int i = 0; i < m; i++) {
board[i] = readRow(gen, i, n);
}
return board;
}
// ==================== Demo ====================
public static void main(String[] args) {
// Example 1
System.out.println("=== Example 1 ===");
int[][] board1 = {
{0, 1, 0},
{0, 0, 1},
{1, 1, 1},
{0, 0, 0}
};
filesystem.clear();
initialize(board1);
printBoard("Input:", board1);
nextGen(0, board1.length, board1[0].length);
int[][] result1 = readBoard(1, board1.length, board1[0].length);
printBoard("Output:", result1);
// Example 2
System.out.println("=== Example 2 ===");
int[][] board2 = {
{1, 1},
{1, 0}
};
filesystem.clear();
initialize(board2);
printBoard("Input:", board2);
nextGen(0, board2.length, board2[0].length);
int[][] result2 = readBoard(1, board2.length, board2[0].length);
printBoard("Output:", result2);
}
private static void printBoard(String label, int[][] board) {
System.out.println(label);
for (int[] row : board) {
System.out.println(" " + Arrays.toString(row));
}
System.out.println();
}
}Editor is loading...
Leave a Comment