정수형 요소로 이루어진 배열 하나와 행·열 크기가 주어진 행렬(2차원 배열)이 있을 때, 배열의 요소들이 행렬의 각 행에 몇 개씩 존재하는지 개수를 계산하는 것이 이 글의 목표입니다.
예제 1
입력
int arr[] = { 2, 4, 6 }
int matrix[row][col] = { { 2, 4, 6 }, { 3, 4, 6 }, { 6, 2, 1 } }출력
Elements of array in row 1 are: 3
Elements of array in row 2 are: 2
Elements of array in row 3 are: 2
설명
배열에는 2, 4, 6이라는 세 개의 요소가 있습니다. 이 요소들을 행렬의 각 행과 비교하여 등장 횟수를 확인합니다.
- 1행에는 2, 4, 6이 모두 존재하므로 개수는 3
- 2행에는 4와 6만 존재하므로 개수는 2
- 3행에는 2와 6만 존재하므로 개수는 2
예제 2
입력
int arr[] = { 1, 3 }
int matrix[row][col] = { { 1, 4, 6 }, { 3, 1, 6 }, { 6, 2, 4 } }출력
Elements of array in row 1 are: 1
Elements of array in row 2 are: 2
Elements of array in row 3 are: 0
설명
배열에는 1과 3이라는 두 개의 요소가 있습니다. 각 행과 비교한 결과는 다음과 같습니다.
- 1행에는 1만 존재하므로 개수는 1
- 2행에는 1과 3이 모두 존재하므로 개수는 2
- 3행에는 1과 3이 모두 없으므로 개수는 0
해결 접근 방법
이 문제는 여러 가지 방법으로 해결할 수 있으며, 대표적으로 단순 탐색(Brute Force) 방식과 해시 기반의 효율적 방식이 있습니다. 먼저 단순한 방법부터 살펴보겠습니다.
1. 단순 탐색(Naive) 접근
- 정수형 배열과 행·열 크기를 가진 행렬을 입력받습니다.
- 배열의 크기를 계산한 뒤, 배열·행렬·배열 크기를 함수에 전달하여 처리합니다.
- 행렬의 각 행에 존재하는 배열 요소의 개수를 저장할 임시 변수
count를 선언합니다. - 0부터 행렬의 행 크기까지 반복하는 FOR 루프를 시작합니다.
- 루프 내부에서 0부터 배열의 크기까지 반복하는 FOR 루프를 시작합니다.
- 임시 변수
temp에arr[k]값을 저장합니다. - 다시 0부터 행렬의 열 크기까지 반복하는 FOR 루프를 시작합니다.
- 루프 안에서
temp == matrix[i][j]라면count를 1 증가시킵니다. - 행이 바뀔 때마다
count를 0으로 초기화합니다. - 각 행의 결과를 출력합니다.
이 방법은 세 겹의 루프를 사용하므로 시간 복잡도는 O(row × col × size)입니다.
2. 효율적(Efficient) 접근 — unordered_map 활용
- 정수형 배열과 행·열 크기를 가진 행렬을 입력받습니다.
- 배열의 크기를 계산한 뒤, 배열·행렬·배열 크기를 함수에 전달하여 처리합니다.
- 0부터 행렬의 행 크기까지 반복하는 FOR 루프를 시작합니다.
- 각 행마다
unordered_map변수를 생성합니다. - 0부터 행렬의 열 크기까지 반복하며
um[matrix[i][j]] = 1로 설정하여 해당 행의 모든 값을 해시 맵에 저장합니다. - 개수를 저장할 임시 변수
count를 선언합니다. - 0부터 배열의 크기까지 반복하며
um[arr[j]] == 1인 경우count를 1 증가시킵니다. - 각 행의 결과를 출력합니다.
해시 맵을 사용하면 값의 존재 여부를 O(1)에 확인할 수 있어, 전체 시간 복잡도가 O(row × (col + size))로 크게 개선됩니다.
예제 코드 (단순 탐색)
#include<bits/stdc++.h>
using namespace std;
#define row 3
#define col 3
void arr_matrix(int matrix[row][col], int arr[], int size){
int count = 0;
// 행렬의 행 순회
for(int i=0; i<row; i++){
// 배열 순회
for(int k=0 ; k<size ; k++){
int temp = arr[k];
// 행렬의 열 순회
for(int j = 0; j<col; j++){
if(temp == matrix[i][j]){
count++;
}
}
}
cout<<"Elements of array in row "<< i + 1 <<" are: " << count << endl;
count = 0;
}
}
int main(){
int matrix[row][col] = { { 2, 4, 6 }, {3, 4, 6}, {6, 2, 1}};
int arr[] = { 2, 4, 6};
int size = sizeof(arr) / sizeof(arr[0]);
arr_matrix(matrix, arr, size);
}
출력
위 코드를 실행하면 다음과 같은 결과가 출력됩니다.
Elements of array in row 1 are: 3
Elements of array in row 2 are: 2
Elements of array in row 3 are: 2
예제 코드 (효율적 접근)
#include <bits/stdc++.h>
using namespace std;
#define row 3
#define col 3
void arr_matrix(int matrix[row][col], int arr[], int size){
for (int i = 0; i < row; i++){
unordered_map<int, int> um;
for (int j = 0; j < col; j++){
um[matrix[i][j]] = 1;
}
int count = 0;
for (int j = 0; j < size; j++) {
if (um[arr[j]])
count++;
}
cout<<"Elements of array in row "<< i + 1 <<" are: " << count << endl;
}
}
int main(){
int matrix[row][col] = { { 2, 4, 6 }, {3, 4, 6}, {6, 2, 1}};
int arr[] = { 2, 4, 6};
int size = sizeof(arr) / sizeof(arr[0]);
arr_matrix(matrix, arr, size);
}
출력
위 코드를 실행하면 단순 탐색 버전과 동일한 결과가 출력됩니다.
Elements of array in row 1 are: 3
Elements of array in row 2 are: 2
Elements of array in row 3 are: 2
마무리
두 방법 모두 동일한 결과를 반환하지만, 데이터 크기가 커질수록 unordered_map을 활용한 효율적 접근이 훨씬 빠른 성능을 보입니다. 실무에서는 중첩 루프를 줄이고 해시 자료구조로 조회 시간을 단축하는 것이 권장됩니다.