2024 - 02 - 08 C++ 코딩테스트 10주완성 D+3
*메모리와 주소
RAM은 1Byte 단위의 메모리 셀들로 이루어져 있다.
각각의 메모리 셀들은 16진수로 이루어진 주소를 가지고 있다.
각각의 변수를 선언할 시 해당되는 변수의 크기만큼 메모리에 할당이 된다.
변수의 주소는 사용하는 메모리의 첫번째 주소로 할당받음 => 첫번째 주소를 알면 변수의 크기로 변수의 끝주소까지 알기때문
실습코드
int main()
{
//메모리와 주소
int i;
cout << &i << "\n";
}
*포인터
메모리의 주소를 담는 타입
실습코드
int main()
{
//포인터
int pointerInt = 4;
int* pointer = &pointerInt;
}
*= 에스터리스크
타입에 관계없이 포인터변수의 크기는 32bit 일때 4byte ,64bit 일때 8byte 이다.
실습코드
int main()
{
//포인터
int pointerInt = 4;
int* pointer = &pointerInt;
}
*역참조 연산자
포인터 변수안에 담긴 주소로 접근하여 값을 가져오는 연산자
실습코드
int main()
{
//역참조 연산자
string sa = "hyukjun";
string* sb = &sa;
cout << sb << endl;
cout << sa << endl;
}
*메모리와 포인터
배열의 이름 = 배열이 시작하는 첫번째 주소를 가르킴
포인터변수안에 배열을 할당할경우 주소만 들어가고 배열의 크기정보는 없어짐
실습코드
int main()
{
//포인터와 배열
int ar[3] = { 1,2,3 };
int* c = a;
cout << c << "\n";
cout << &ar[0] << "\n";
//int형 포인터 주소에서 +1을 더하면 int형의 데이터크기만큼 주소를 이동한다.
//따라서 배열의 다음주소를 가르킨다
cout << c + 1 << "\n";
cout << &ar[1] << "\n";
return 0;
}
*중복된 요소 제거하는 방법과 unique()
범위안의 있는 요소 중 앞에서부터 서로 비교해가며 중복되는 요소를 제거하고 나머지 요소들은 삭제하지 않고 그대로 두는 함수.
실습 코드
int main()
{
//중복된 요소제거 unique 사용
for (int i = 1; i <= 5; i++)
{
v.push_back(i);
v.push_back(i);
// 1 1 2 2 3 3 4 4 5 5
}
for (int i : v) cout << i << "";
cout << "\n";
// 중복되지 않는 요소로 채운 후, 그 다음 이터레이터를 반환한다.
auto it = unique(v.begin(), v.end());
cout << it - v.begin() << '\n';
// 앞에서 부터 중복되지 않게 채운 후 나머지 요소들은 그대로 둔다.
for (int i : v) cout << i << "";
cout << '\n';
return 0;
}
이중 it - v.begin() 에서 이터레이터인 it 에서 v.begin을 빼는 이유는
unique 는 해당 자료형으로부터 이터레이터를 반환하기때문에 몇번째인지 추려내려면 이 이터레이터에서 배열의 초깃값을 빼주어야 함.
*erase 함수
배열의 특정부분을 지우고 싶을때 사용하는 함수
실습코드
int main()
{
vector<int> v{ 1,1,2,2,3,3 };
// 중복되지 않은 요소로 채우고, 그 다음 요소들을 삭제하고 싶다면..
// erase의 첫번째 인자는 지우기 시작하는 시작점 이고
// 안에 들어간 첫번째 인자 unique(v.begin(),v.end())는 중복되지 않은 요소 다음 이터레이터를 반환하기때문에
// 중복되지 않은 요소를 채우고 그 다음 요소들을 삭제할수있다.
v.erase(unique(v.begin(), v.end()), v.end());
}
*makePermutation 동작원리
n = 배열의 총 갯수
r = 순열로 뽑을 부분 배열의 갯수
depth = 배열 요소끼리 스왑을 하기 위한 기본 정수형 요소
인수가 3,3,0 이면
printf 조건이 r == depth 일때이므로 depth가 3까지 올라간경우만 생각
Swap 같은 경우 다시 본래자리로 swap을 해주므로 밑 swap 코드는 생각하지않기
재귀함수의 경우 재귀함수가 리턴을 받을때까지 밑에코드가 진행되지 않는다.
i = 0 일때
swap (0,0) => make(3,3,1) => swap(1,1) => make(3,3,2) => swap(2,2) => make(3,3,3) => 1,2,3
swap (2,1) => a[] = 1,3,2 => make(3,3,3) => 1,3,2
i = 1 일때
swap (1,0) => a[] = 2,1,3 => make(3,3,1) => swap(1,1) => make(3,3,2) => swap(2,2) => make(3,3,3) => 2,1,3
각 swap을 한상태에서 재귀함수가 도는 것이므로 맨앞 배열순서를 제외한 나머지 두개가 바뀐다.
i = 2 일떄
swap (2,0) => a[] = 3,1,2 => make(3,3,1) => swap(1,1) => make(3,3,2) => swap(2,2) => make(3,3,3,) => 3,1,2
각 swap을 한상태에서 재귀함수가 도는 것이므로 맨앞 배열순서를 제외한 나머지 두개가 바뀐다.