我在一次采访中被问到这个问题(我无法破解)。我仍然很想知道如何解决这个问题。
我必须设计一个类似棋盘的结构,我必须存储 1 而不是黑色区域和 0 而不是白色区域,最多 4 行和列。该程序可以用 C 或 java 解决。我知道这必须是一个简单的答案。
谁能帮我解决这个问题?谢谢
该算法并不太难,即使对于任意大小的数组也是如此:
首先,分配一个适当大小的二维数组。在某些语言中,您需要手动分配每一行。Java 和 C 都可以为您做到这一点。爪哇:int[][] board = new int[w][h]
然后,对于每一行、每一列,计算单元格应该是黑色还是白色:
(x+y)%2
。(x+y)&1
.x%2 ^ y%2
或者x&1 ^ y&1
where^
表示按位异或。(x^y)%2
或(x^y)&1
.2
奇数位置。两种语言(以及所有其他类 c 语言)都支持经典的 for 循环:
for(int i = 0; i < size; i++)
i = 0
发生在循环之前,是声明迭代变量的最佳位置。i < size
在每次迭代之前计算,如果它是假的(0
在 C 中,false
在 Java 中),迭代停止。i++
在每次迭代后计算。
大多数语言将数组大小与数组一起存储。在 C/C++ 中,您必须单独存储数组大小或使用类似std::array
or的智能数组std::vector
。您还必须小心不要访问数组外部(Java 会引发异常,但 C/C++ 允许您写入随机的内存块——这是导致远程程序行为不端的好方法)。
C 不允许你声明一个在编译时大小未知的数组。如果你想要这个,你需要一个指向指针数组的指针(int**
- 不要忘记取消/分配每一行),或者展平数组(int*
- 更高效的内存,但你需要board[x + w*y]
访问单元格) .
当然,如果在编译时知道大小并且足够小,您可以只使用数组文字并完成它;int[][] board = new int[][]{{0,1,0,1}, {1,0,1,0}, {0,1,0,1}, {1,0,1,0}}
Java(省略的部分是读者的练习):
int[][] board = new int[h][w];
for(int x ...){
for(int y ...){
board[y][x] = (x+y)%2;
}
}
为了比较,这里是 Ruby:
board = Array.new(h) {|y|
Array.new(w) {|x|
(x+y)%2
}
}
#or (this time inlined)
board = (0...h).map{|x| (0...w).map{|y| (x+y)%2 }}
您可以使用位数组并将 4x4 板存储在单个整数中。
bin hex
1010 A
0101 5
1010 A
0101 5
=>
int board = 0xA5A5;
您可以在一个单元格中设置值,由 2 个索引i
[0..3] 和j
[0..3] 指定,其中:
int i = 1;
int j = 2;
board |= (1 << (i*4+j));
或清除单元格中的值:
board &= ~(1 << (i*4+j));
您可以通过以下方式发现单元格中的值:
printf("cell at (%d,%d) has value %d\n", i, j, (board >> (i*4)+j) & 1);
用所需的模式填充空白“结构”,
board = 0;
for (i=0; i < 4; i++)
for (j=0; j < 4; j++)
if (!((i+j)%2))
board |= (1 << (i*4+j));
总商会:
#include <stdio.h>
int main() {
int i,j,board;
for (i=0; i < 4; i++)
for (j=0; j < 4; j++)
if ((i+j)%2)
board &= ~(1 << (i*4+j));
else
board |= (1 << (i*4+j));
for (i=0; i < 4; i++) {
for (j=0; j < 4; j++) {
printf("%d ", (board >> (i*4+j)) & 1);
}
printf("\n");
}
return 0;
}