https://www.codewars.com/kata/5263a84ffcadb968b6000513/solutions/cpp
지난 번 풀이가 아주 그래서..
https://velog.io/@mir21c/Number-of-Proper-Fractions-with-Denominator-d-4kyu
쉬어갈 겸, 추천으로 뜬 5 kyu를 하나 작성했습니다.
문제랄 것도 없는 문제입니다.
그냥 행렬 곱하기 구현입니다.
std::vector<std::vector<int>> matrix_multiplication(std::vector<std::vector<int>> &a, std::vector<std::vector<int>> &b, size_t n)
{
std::vector<std::vector<int>> ret;
int n1 = a.size();
int m1 = a[0].size();
int n2 = b.size();
int m2 = b[0].size();
ret.resize(n1);
for (int r = 0; r < n1; ++r)
{
ret[r].resize(m2);
}
for (int r = 0; r < n1; ++r)
{
for (int c = 0; c < m2; ++c)
{
int sum = 0;
for(int m = 0; m< m1; ++m)
{
sum +=a[r][m] * b[m][c];
}
ret[r][c]=sum;
}
}
return ret;
}
설명할 것도 없네요.
하나만 추가하자면,
필드에서는 대부분 아마 라이브러리를 사용할 것이기 때문에 직접 구현할 일은 없겠지만, 행렬을 많이 다루는 개발자 입장에서는 항상 행과 열이 헷갈리는 경우가 많기 때문에, 행렬을 다룰 때 제가 익숙한 방식에 대해 조금 더 언급하겠습니다.
예를 들어 2차원 행렬을 정의할 때 행(row)을 먼저 정의하고, 하위를 열(column)으로 정의하는 것이 좋습니다. 아래 처럼요.
int rowNo = 4;
int colNo = 6;
int ** m = new int*[rowNo];
for(int r = 0; r< rowNo;++r)
{
m[r] = new int[colNo];
}
위 문제에서는 2중 vector를 사용했는데,
순서대로 상위 vector가 행(row), 하위가 열(column).
그리고 데이터에 접근을 하기위해 순회를 할 때에도
행열 순으로 하는 것이 좋습니다. x, y 좌표계로 본다면, y -> x 순서입니다. 네이밍도 저같은 경우는 row는 r, column은 c로 두어서 최대한 안 헷갈리게 하는 편입니다.
for(int r = 0; r< rowNo ; ++r)
for(int c = 0; c< colNo ; ++c)
int a = m[r][c];
이 순서를 반대로 해도 상관은 없지만, 위와 같이 하는 것이 메모리 관점에서 조금 더 빠릅니다. 그리고 이런 저런 행렬관련 또는 이미지관련 작업들을 하다보면, 이 순서를 지키는 것이 좀 간편합니다.