固定大小矩阵中数独单元格邻居的最优计算方法问询
数独求解器中Neighbors函数的优化需求
我正在完成大学作业,用C语言实现数独求解器,其中需要实现neighbors函数,用于计算指定单元格的邻居——也就是值域受该单元格值约束的单元格。数独里,单元格的邻居是其所在同行、同列及同3×3区块所有单元格的并集。
同行和同列的邻居可以通过循环轻松计算,但3×3区块的邻居因为单元格在区块内的位置不同,我现在写了9种独立场景处理,代码非常冗余。考虑到只依赖libc,且其他地方不需要集合或动态列表这类数据结构,我不想自行实现它们来存储并去重邻居。
以下是我当前的实现代码:
/* * neighbours * Auxiliary function to populate array with neighbour indices for cell (x) specified by index (idx). * That is, populate the array with indices of the cells such that constraints on their domain depend on value of x. * This function is only declared to increase level of abstraction and simplify coding. * It also doesn't generalize for different board sizes as it assumes all cells have 20 neighbours. * It is not intended to be used outside the scope of ac3, and therefore is marked auxiliary. * * @param idx index of the cell which neighbours are to be determined * @param buf a pointer to integer array with at least 20 elements (20 are populated) * @return 1 if successful, 0 otherwise */ int neighbours(int idx, int* buf); int neighbours(int idx, int* buf) { int x, y, partition_x, partition_y, cursor; cursor = 4; x = idx % BOARD_WIDTH; y = idx / BOARD_WIDTH; partition_x = x % 3; partition_y = y % 3; if (partition_x == 0 && partition_y == 0) { buf[0] = IDX(x+1, y+1); buf[1] = IDX(x+2, y+2); buf[2] = IDX(x+2, y+1); buf[3] = IDX(x+1, y+2); } if (partition_x == 0 && partition_y == 1) { buf[0] = IDX(x+1, y-1); buf[1] = IDX(x+2, y+2); buf[2] = IDX(x+2, y-1); buf[3] = IDX(x+1, y+2); } if (partition_x == 0 && partition_y == 2) { buf[0] = IDX(x+1, y-1); buf[1] = IDX(x+2, y-2); buf[2] = IDX(x+2, y-1); buf[3] = IDX(x+1, y-2); } if (partition_x == 1 && partition_y == 0) { buf[0] = IDX(x-1, y+1); buf[1] = IDX(x+1, y+2); buf[2] = IDX(x+1, y+1); buf[3] = IDX(x-1, y+2); } if (partition_x == 1 && partition_y == 1) { buf[0] = IDX(x-1, y-1); buf[1] = IDX(x+1, y+2); buf[2] = IDX(x+1, y-1); buf[3] = IDX(x-1, y+2); } if (partition_x == 1 && partition_y == 2) { buf[0] = IDX(x-1, y-1); buf[1] = IDX(x+1, y-2); buf[2] = IDX(x+1, y-1); buf[3] = IDX(x-1, y-2); } if (partition_x == 2 && partition_y == 0) { buf[0] = IDX(x-1, y+1); buf[1] = IDX(x-2, y+2); buf[2] = IDX(x-2, y+1); buf[3] = IDX(x-1, y+2); } if (partition_x == 2 && partition_y == 1) { buf[0] = IDX(x-1, y-1); buf[1] = IDX(x-2, y+2); buf[2] = IDX(x-2, y-1); buf[3] = IDX(x-1, y+2); } if (partition_x == 2 && partition_y == 2) { buf[0] = IDX(x-1, y-1); buf[1] = IDX(x-2, y-2); buf[2] = IDX(x-2, y-1); buf[3] = IDX(x-1, y-2); } for (int nx = 0; nx < BOARD_WIDTH; nx++) { if (nx == x) continue; buf[cursor] = IDX(nx, y); cursor++; } for (int ny = 0; ny < BOARD_WIDTH; ny++) { if (ny == y) continue; buf[cursor] = IDX(x, ny); cursor++; } return 1; }
内容的提问来源于stack exchange,提问作者Nikolai Savulkin
相关产品推荐
相关产品推荐

