Нам обычно задают этот вопрос, основываясь на игре «Жизнь»:
У вас есть 2D-массив, элементы которого равны 0 или 1, и он следует следующему правилу:
- Любая живая клетка с менее чем двумя живыми соседями умирает, как если бы это было вызвано недостаточным населением.
- Любая живая клетка с двумя-тремя живыми соседями живет до следующего поколения.
- Любая живая клетка с более чем тремя живыми соседями умирает, как будто от перенаселения
- Любая мертвая клетка, имеющая ровно три живых соседа, становится живой клеткой, как бы путем размножения.
Это решение немного сложно понять, если вы не хотите создавать еще один 2D-массив и использовать обмен местами.
Объяснение:
Прежде всего, вам нужно будет пройти по каждой строке и столбцу, и для каждой строки и столбца вам нужно будет проверить все 8 соседей вокруг него. верхний, нижний, боковой и диагональный. Также вам нужно иметь в виду, что при проверке вашего левого/правого/верхнего/нижнего элемента не следует выходить за границы массива. Например, вы проверяете первую строку и, как обычно, проверяете [строку-1], она выйдет из массива. Точно так же, если вы находитесь в самом правом углу и отметите [col+1], он выйдет за границы.
Поэтому мы будем использовать приведенный ниже трюк,
Для каждой строки мы проходим через каждый столбец и для каждой строки, элемента столбца мы проходим еще два цикла внутри него от i=0;i‹ 3 и j=0; j ‹ 3. Это даст нам все восемь соседей ячейки
Мы создадим массив, такой как int[] Neighbours = { 0, 1, -1 };
Теперь посмотрите на часть кода ниже:
******************************
for (int row = 0; row ‹ rows; row++) {
for (int col = 0; col ‹ cols; col++) {
int liveneighbours = 0;
for (int i = 0; i ‹ 3; i++) {
for (int j = 0; j ‹ 3; j++) {
if (!(neighbours[i] == 0 && Neighbours[j] == 0)) {
int r = row + Neighbours[i];
int c = col + Neighbours[j];
if ((r ›= 0 && c ›= 0 && r ‹ rows && c ‹ cols) && (Math.abs(arr[r][c]) == 1)) {
liveneighbours++;
}} }}
****
В первом цикле есть строка, а во втором - столбец, поэтому начните с
строка = 0 и столбец = 0
Теперь вы начинаете свой цикл с i = 0 до j‹ 3
вы вычисляете r= row+neighbours[i] = 0+0 и c=col+neighbours[j] = 0+0=0
если оба равны 0, вы не входите в условие if и ничего не делаете
Далее i=0 и j=1
r=строка+соседи[i] = 0+соседи[0]=0
c=столбец+соседи[j]=0+1=1
это дает вам arr[0][1], следующее из arr[0][0]
аналогично далее i=0 и j=2
r=строка+соседи[i] = 0+соседи[0]=0
c=col+neighbours[j]=0+neighbours[2] = 0+(-1)=-1
он дает arr[0][-1], но выходит за край, поэтому, если условие позаботится об этом..
Точно так же вы выбираете i=1 и j=1
r=строка+соседи[i] = 0+соседи[1]=1
c=col+neighbours[j]=0+neighbours[1] = 1, поэтому мы ищем arr[1][1], который является соседом arr[0][0], и проверяем его значение, если оно равно 1, мы увеличит количество живых соседей на 1
Например.. возьмите строку = 2 и столбец = 2.
мы начнем с i=0;j=1 (мы не можем взять i=0 и j=0, так как они приведут к одному и тому же элементу)
г=строка+соседи[я] = 2+0=2
c=столбец+соседи[j]=2+1=3
поэтому он становится следующим соседом arr[2,3]
тогда я=0 и j=2
г=строка+соседи[я] = 2+0=2
c=столбец+соседи[2]=2-1=1
поэтому он становится arr[2,1], который является более ранним соседом
Таким образом, мы вычисляем соседей, и если сосед 2 или 3 в зависимости от условия, мы делаем его 2, если он был мертв и получил 3 соседей и стал живым. аналогично делаем -1 он был жив и сдох из-за соседей меньше 2 и 3
if(arr[row][col]==0 && liveneighbours==3)
arr[row][col]=2;
if(arr[row][col]==1 &&(liveneighbours›3 || liveneighbours ‹2))
arr[row][col]=-1;
И, наконец, мы проходим через массив, и если ячейка больше 0, это означает, что она жива, и делаем ее 1, иначе 0