병렬 배열상황에 따라서 다차원 배열(multidimensional array)을 사용해야 하는 경우 가 있다
다차원 배열을 사용한다고 하면 일반적으로 2차원 배열의 사용을 의미하지만 3차원 이상의 배열도 가능하다
2차원 배열(two-dimensional array)은 행(row)과 열(column)이라는 2개의 인덱스를 사용해
요소를 저장하는 구조화된 자료형을 의미
int scores[5][3];
첫 번째 인덱스는 행을 나타내며 두 번째 인덱스는 열을 나타낸다
즉 scores라는 이름의 배열은 int형으로 5행 3열의 인덱스를 갖는 거다
int scores [5][3] = { {82, 65, 72},
{73, 70, 80},
{91, 76, 40},
{72, 72, 68},
{65, 90, 80} };
초기화는 위와 같이 진행해 줄 수 있다.
int scores [5][3] = {0};
모든 요소를 0으로 초기화 할려면 위와 같이 해도 된다.
scores[1][0] = 5; // 1행 0열에 5 저장
cin >> scores[2][1]; // 2행 1열에 값 입력받기
x = scores[1][2]; // 1행 2열의 값을 변수 x에 복사
cout << scores[0][0]; // 0행 0열의 값을 출력
요소에 접근할 때는 위와 같이 하면 된다
void function(int array[ ] [3] , int rowSize);
배열을 함수의 매개변수로 전달할 때는 위와 같이
첫 번째 대괄호는 비어있지만, 두 번째 대괄호에는 두 번째 차원의 크기를 정의해줘야 한다
하나의 행이 몇개로 이루어져 있는지 알려줘야 한다.
몇가지 재밌는 코드를 보여주겠다
2차원 배열 행으로 접기
for (int i = 0 ; i < rowSize ; i++)
{
for (int j = 0 ; j < colSize ; j++)
{
foldedArray [rowSize -1 - i][j] = originalArray [i][j];
}
}
행을 거꾸로 뒤집는다
2차원 배열 열로 접기
for (int i = 0 ; i < rowSize ; i++)
{
for (int j = 0 ; j < colSize ; j++)
{
foldedArray [i][colSize -1 -j] = originalArray [i][j];
}
}
열을 거꾸로 뒤집는다
2차원 배열 대각선으로 접기(전치)
for (int i = 0 ; i < orgRowSize ; i++)
{
for (int j = 0 ; j < orgColSize ; j++)
{
trasposedArray [j][i] = originalArray [i][j];
}
}
행열 순서를 바꿔준다
이걸 바탕으로 선형 변환하는 코드를 구현해봤다.
/*******************************************************************
* 이 프로그램은 2차원 배열을 행 기준 또는 열 기준으로 변환하여 *
* 두 개의 1차원 배열로 만드는 방법을 보여줍니다. *
*******************************************************************/
#include <iostream>
#include <iomanip>
using namespace std;
/****************************************************************
* rowTransform 함수는 2차원 배열을 행 기준(row-by-row)으로 읽어 *
* 1차원 배열로 변환합니다. 첫 번째 배열은 변경을 방지하기 위해 *
* const로 전달됩니다. *
****************************************************************/
void rowTransform(const int originArray[][4], int rowSize, int rowArray[])
{
int i = 0;
int j = 0;
for (int k = 0; k < 8; k++)
{
rowArray[k] = originArray[i][j];
j++;
if (j > 3)
{
i++;
j = 0;
}
}
}
/******************************************************************
* colTransform 함수는 2차원 배열을 열 기준(column-by-column)으로 *
* 읽어 1차원 배열로 변환합니다. 첫 번째 배열은 변경을 방지하기 위해 *
* const로 전달됩니다. *
******************************************************************/
void colTransform(const int originArray[][4], int rowSize, int colArray[])
{
int i = 0;
int j = 0;
for (int k = 0; k < 8; k++)
{
colArray[k] = originArray[i][j];
i++;
if (i > 1)
{
j++;
i = 0;
}
}
}
/***************************************************************
* 이 함수는 2차원 배열의 내용을 출력합니다. *
* 배열은 const로 전달되어 변경되지 않습니다. *
***************************************************************/
void printTwoDimensional(const int twoDimensional[][4], int rowSize)
{
for (int i = 0; i < rowSize; i++)
{
for (int j = 0; j < 4; j++)
{
cout << setw(4) << twoDimensional[i][j];
}
cout << endl;
}
cout << endl;
}
/***************************************************************
* 이 함수는 1차원 배열의 내용을 출력합니다. *
* 배열은 const로 전달되어 변경되지 않습니다. *
***************************************************************/
void printOneDimensional(const int oneDimensional[], int size)
{
for (int i = 0; i < size; i++)
{
cout << setw(4) << oneDimensional[i];
}
cout << endl;
}
int main()
{
// 배열 선언 및 첫 번째 배열 초기화
int originArray[2][4] = {{0, 1, 2, 3}, {10, 11, 12, 13}};
int rowArray[8];
int colArray[8];
// 변환 함수 호출 (행 기준 / 열 기준)
rowTransform(originArray, 2, rowArray);
colTransform(originArray, 2, colArray);
// 2차원 배열 출력
cout << "원본 배열 (2차원 배열)" << endl;
printTwoDimensional(originArray, 2);
// 행 기준 변환 배열 출력
cout << "행 기준 변환된 배열 (1차원): ";
printOneDimensional(rowArray, 8);
// 열 기준 변환 배열 출력
cout << "열 기준 변환된 배열 (1차원): ";
printOneDimensional(colArray, 8);
return 0;
}
행 중심으로 변환하는 함수
열 중심으로 변환하는 함수
이차원 배열 출력하는 함수
일차원 배열 출력하는 함수
총 4개로 구성돼 있다
다음은 2차원 배열로 구현한 빈도 배열 히스토그램 코드이다.
/******************************************************************
* 이 프로그램은 파일에서 정수 목록을 읽어들이고, *
* 0부터 9까지(포함)의 값에 대해 빈도 배열과 히스토그램을 생성합니다. *
******************************************************************/
#include <iostream>
#include <fstream>
#include <iomanip>
using namespace std;
int main()
{
// 상수 및 변수 선언과 초기화
const int CAPACITY = 10;
int frequencies[CAPACITY] = {0}; // 각 숫자(0~9)의 빈도 저장
ifstream integerFile;
// 정수 파일 열기
integerFile.open("integerFile.dat");
if (!integerFile)
{
cout << "오류: 정수 파일을 열 수 없습니다." << endl;
cout << "프로그램을 종료합니다." << endl;
return 0;
}
// 파일로부터 정수를 읽어 빈도 배열 생성
int data;
int size = 0;
while (integerFile >> data) {
if (data >= 0 && data <= 9) {
size++;
frequencies[data]++;
}
}
// 파일 닫기
integerFile.close();
// 유효한 데이터 개수 및 히스토그램 출력
cout << "유효한 데이터 항목 수: " << size << "개" << endl;
for (int i = 0; i < 10; i++)
{
cout << setw(3) << i << " ";
for (int f = 1; f <= frequencies[i]; f++)
{
cout << '*'; // 해당 숫자의 빈도만큼 '*' 출력
}
cout << " " << frequencies[i] << endl; // 빈도 수 함께 출력
}
return 0;
}
결과
실행 결과:
유효한 데이터 항목 수: 202개
0 ********************** 22
1 **** 4
2 ******************* 19
3 ************* 13
4 ******************** 20
5 ********************************* 33
6 **************************** 28
7 **************************** 28
8 ************************* 25
9 ********** 10
integerFile.dat는 아래와 같다
1 3 2 2 5 7 3 2 8 0 6 4 6 7 0 7 8 5 4 2 3 0 6 7 5 8 5 4 8 9 6 5 5 9 2 3 5 2 6 7 8
0 6 4 6 7 0 7 8 5 4 2 13 0 6 7 5 8 5 4 8 9 6 7 0 7 8 5 4 2 3 0 6 7 5 8 5 4 8 9 6 5
2 7 0 7 8 5 4 2 3 0 6 7 5 8 5 4 8 9 6 15 5 9 7 0 7 8 5 4 2 3 0 6 7 5 8 9 6 5 6 6 4
5 9 7 0 7 8 5 4 2 3 0 6 7 5 8 9 6 5 6 6 4 2 7 0 7 8 5 4 2 3 0 6 7 5 8 5 4 8 9 6 5
1 3 2 2 5 7 3 2 8 0 6 4 6 17 0 7 8 5 4 2 3 0 0 6 4 6 7 0 7 8 5 4 2 3 0 6 7 5 8 1 1
integerFile은 파일과 연결될 입력 스트림 객체의 이름이다.
즉, integerFile이라는 이름의 파일 입력용 객체를 선언하는 것이고
"integerFile.dat"라는 이름의 파일을 열어서, integerFile 스트림 객체에 연결한 것이다
그리고 파일 열기에 실패하면 오류문구를 출력하고 종료한다
코드가 계속 진행된다면 파일 열기에 성공했다는 것이고
data를 하나씩 읽어오는 과정을 거친다.
data가 0보다 크고 0보다 작으면 size를 1+ 하고 frequencies 배열의 [data] 요소조 1 증가시킨다
그 결과 for문에 들어가 출력을 반복하면 결과의 화면이 나온다
댓글