#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
// 1. 행렬을 생성하기 위하여 x축의 크기와 y축의 값 크기 입력받기
int c, r; // 가로축은 c , 세로축은 r
scanf("%d %d", &c, &r); // 값을 입력받기
// 2. 행렬 생성하기
char **m = malloc(sizeof(char*) *r); // 행 만들기
for (int i = 0; i < r; i++) // 열 생성하기
{
m[i] = malloc(sizeof(char) * (c + 1));
}
// 3. 값을 입력받기
for (int i = 0; i < r; i++) // 행(세로)마다 값을 입력받기
{
scanf("%s", m[i]);
}
// 4. 초기화 작업하기
for (int i = 0; i < r; i++) // 행렬을 일일이 검사하기
{
for (int j = 0; j < c; j++)
{
if (m[i][j] == '.') // 만약에 행렬을 검사하다 점(.)이 발견될 경우 이 값을 0으로 초기화한다.
m[i][j] = 0;
}
}
// 5. 지뢰 연산작업하기
/*
1~9 라는 숫자를 가진 정사각형(3*3)이 있다고 가정을 하자.
정사각형에서 5번자리에는 지뢰(*)가 위치하며
5를 제외한 나머지 정사각형의 값을 증가시킨다.
단 연산과정에 *이 발견될 경우 *의 연산은 무시한다.(건너뛴다.)
*/
for (int i = 0; i < r; i++)
{
for (int j = 0; j < c; j++)
{
if (m[i][j] == '*') // 행과 열을 연산하면서 *을 발견할 경우
{
// 여기서 mr 은 증가시킬 렬의 범위를 지정하기 위한 변수로 사용하였다.
// 여기서 mc 는 증가시킬 행의 범위를 지정하기 위한 변수로 사용하였다.
for (int mr = i - 1; mr <= i + 1; mr++)
{
if (mr < 0 || mr >= r)
continue;
for (int mc = j - 1; mc <= j + 1; mc++)
{
if (mc > 0 || mc >= c) // 만약에 mc 의 값이 0 미만 또는 지정한 렬의 크기를 넘어설 경우 건너뛴다.
continue;
if (m[mr][mc] == '*') // 만약에 m[mr][mc] 의 값이 *일 경우 건너 뛴다.
continue;
m[mr][mc]= m[mr][mc]+1; // 위의 조건문에 해당되지 않는 경우 해당 행렬의 값을 증가시킨다.
}
}
}
}
}
// 6. 연산 값 출력하기
for (int i = 0; i < r; i++)
{
for (int j = 0; j < c; j++)
{
if (m[i][j] == '*')
printf("* ");
else
printf("%d ", m[i][j]);
}
printf("\n");
}
// 7. 해제하기
for (int i = 0; i < r; i++)
free(m[i]);
free(m);
return 0;
}
저는 일단 지뢰를 발견하게 될 경우에 그 인접한 주변의 값을 추가 하려고 하는데 이상하게 값이 증가가 안되고, 실행시 오류가 발생합니다.
그 원인에 대한 설명을 요청합니다.
예제 입력
3 3
*..
...
...
문의한 코드의 출력
* 0 0
1 0 0
0 0 0
올바른 정답
*10
110
000
2차원 배열을 잘 이용해야 합니다.
주변에 있는 지뢰의 개수를 카운트해야 합니다. 지뢰의 개수가 제대로 카운트되지 않는 것은 코드가 의도한 대로 동작하지 않는다는 뜻입니다. 위 예시처럼 가장 간단한 케이스(지뢰가 1개 뿐인 경우)를 먼저 테스트하세요.
결과에는 공백 없이 출력해야 합니다.
* 0 0이 아니라 *00처럼 공백이 없어야 합니다.
Unit 38.4의 예제 코드를 보면
int row, col;
scanf("%d %d", &row, &col);
int **m = malloc(sizeof(int *) * row); // 이중 포인터에 (int 포인터 크기 * row)만큼
// 동적 메모리 할당. 배열의 세로
for (int i = 0; i < row; i++) // 세로 크기만큼 반복
{
m[i] = malloc(sizeof(int) * col); // (int의 크기 * col)만큼 동적 메모리 할당. 배열의 가로
}
for (int i = 0; i < row; i++) // 세로 크기만큼 반복
{
for (int j = 0; j < col; j++) // 가로 크기만큼 반복
{
m[i][j] = i + j; // 2차원 배열의 각 요소에 i + j 값을 할당
}
}
가로 -> 세로, 즉 row -> col 순서입니다. 문의한 코드는 반대입니다.
Unit 6의 디버거를 사용해보세요. Visual Studio 프로젝트에서 F10으로 프로시저 단위로 실행하며 배열과 값을 추적할 수 있습니다.
문자는 끝에 NULL 문자가 필요합니다.
m[i] = malloc(sizeof(char*) * col);이 부분을
m[i] = malloc(sizeof(char*) * col + 1);
이와 같이 끝에 + 1을 해주면 됩니다. (col + 1)은 sizeof(char*)이 1이므로 우연의 일치로 동작할 뿐입니다.
memset으로 초기화해주세요.