C++ Realization - Programers level1 (1)

김정욱·2021년 1월 21일
0

Algorithm - 내용(C++)

목록 보기
5/9

[ 1. v.begin() / v.end() ]

  • v.begin()은 첫번째 요소를 가리킨다
  • v.begin()+1은 두번째 요소를 가리킨다.
  • 여러 함수들을 쓸 때 보통 두번 째 매개변수로 받는 요소 전까지 적용하는 것 같다
/* 1번째요소, 즉 1개로 새로운 벡터 temp에 저장 */ - 주의!!
vector<int> temp(array.begin(), array.begin()+1);
sort(array.begin(), array.begin()+1) --> 첫번째 원소만 sort한다!
sort(array.begin(), array.begin()+2) --> 2번째 원소까지 sort!

/* 1번째요소 ~ 2번째 요소, 즉 2개로 새로운 벡터 temp에 저장 */
vector<int> temp(array.begin(), array.begin()+2); 

/* 1번째요소 ~ 5번째 요소, 즉 5개로 새로운 벡터 temp에 저장 */
vector<int> temp(array.begin(), array.begin()+5);

[ 2. 10진법 -> n진법 ]

    vector<int> v;
  /* 정수 n을 3진법으로 변환시키는 코드! */
    while(n!=0)
    {
        v.push_back(n%3);
        n/=3;
    }
    reverse(v.begin(), v.end());

: 나눈 나머지를 뒤부터 넣어주었기 때문에 reverse로 뒤집어 준 것!

[ 3. 중복원소 없애기 (unique / erase) ]

  vector<int> arr;
  arr.erase(unique(arr.begin(), arr.end()), arr.end());
  • 중복원소를 제거하기 위한 코드이다.
  • <algorithm>헤더에 있는 unique()는 단순히 중복 원소들을 맨 뒤로 밀고
    그 첫 위치를 반환하는 역할을 한다.
  • erase()와 함께 쓰면 중복 원소를 삭제할 수 있다

[ 4. 숫자 / 공백 판별 (isdigit / isspace) ]

  • <cctype>헤더에 있는 isdigit()을 사용하여 입력받은 문자가 숫자인지 판별할 수 있다
#include <cctype>
...
char a = '3';
char b = 'c';
isdigit(a); // true
isdigit(b); // false
  • ```헤더에 있는 isspace()```을 사용하여 입력받은 문자가 공백인지 판별할 수 있다.
    (단순 ' ' 뿐만 아니라 'n' 개행, tab등 다양한 것들이 포함된다 )
#include <cctype>
...
char a = '\n';
char b = '3';
isspace(a); // true
isspace(b); // false

[ 5. find (string / algorithm) ]

  • c++에는 2가지 find 함수가 있다.
    1) string.find()
        : 문자열에서 특정 문자 or 문자열을 찾는데 사용
    string str = "abcdef";
    int r = str.find("de");
    /* 찾는 요소가 있으면 시작하는 인덱스 반환 */
    cout << r <<'\n'; // 3

    /* 찾는 요소가 없으면 -1 반환 */
    r = str.find("gf");
    cout << r << '\n'; // -1

   2) <algorithm> 에 있는 find()
       : vector와 같은 stl요소에서 원하는 특정 값을 찾는데 사용

#include <algorithm>
...
  vector<string> str;
  vector<string>::iterator it = find(str.begin(), str.end(), "찾는문자열");
  if(it != str.end())
   /* 1) 값이 있으면 해당 요소를 가리키는 iterator를 반환 */
  	cout << "값이 있음" << '\n';
  else
   /* 2) 값이 없으면 마지막인 v.end() 가리키는 iterator를 반환 */ 
   cout << "값이 없음" << '\n';

  -----------------------------------------------------------------------

  /* .begin()을 빼주면 해당 요소의 인덱스를 반환 */
  int idx = find(str.begin(), str.end(), "찾는문자열") - str.begin();

[ 6. 소수 구하기 (에라토스테네스의 채) ]

: 일반적으로 소수를 구하는 과정은 O(N^2)의 시간복잡도를 가지지만,
  '에라토스테네스의 채' 방법은 O(N*logN)의 시간복잡도를 가질 수 있다.

#include <string>
#include <vector>

using namespace std;

int solution(int n) {
    int answer = 0;
    /* 에라토스테네스의 체 - 소수를 O(NlogN)으로 구하는 과정 */
    vector<bool> v(n+1, true);
    // 2부터 n까지 배수에 해당하면 본인 빼고 다 false로 체크 후 개수 cnt
    for(int i=2;i<n+1;i++)
    {
        if(v[i] == true)
        {
            for (int j=2; i*j<n+1; j++) v[i*j] = false;
            answer++;
        }
    }
    return answer;
}

: n까지 소수의 개수를 구하는 코드

[ 6. 대 / 소문자 처리 (tolower / toupper) ]

: 특정 문자를 대 / 소문자로 바꾸는 함수

#include <cctype>
...
  char chU = toupper('a'); // A
  char chL = tolower('F'); // f

[ 7. stoi / stof / stoll ]

  • stoi() : string --> int
  • stod() : string --> double
  • stoll() : string --> long long
    (추가적으로 이 함수들은 음수도 처리해준다!)

[ 8. sqrt / abs / pow / powl ]

: 모두 <cmath> 헤더에 포함

  • sqrt() : 제곱근을 구하는 함수
  • abs() : 절대값을 구하는 함수
  • pow() / powl() : 제곱을 구하는 함수
#include <cmath>
...
  /* a의 제곱 + b의 제곱의 제곱근을 구하는 것 ! */
  double result = sqrt(pow(a,2) + pow(b,2));

[ 8. min_element / max_element() ]

: stl 자료구조의 요소들에서 최소 / 최대값을 구하는데 사용
최소값을 가리키는 iterator를 반환

#include <algorithm>
...
  /* vector에서 최소값을 찾아 삭제하는 코드 */
  int min_value = *min_element(arr.begin(), arr.end());
  arr.erase(find(arr.begin(), arr.end(), min_value));
  answer = arr;

[9. 최소 공배수 / 최대 공약수 (유클리드 호제법)]

: a와 b의 최소공배수(lcm) / 최대공약수(gcd)gcd*lcm = a*b를 만족한다
(유클리드 호제법으로 최대공약수를 쉽게 구할 수 있다!)

#include <string>
#include <vector>

using namespace std;

vector<int> solution(int n, int m) {
    vector<int> answer;
    /* 유클리드 호제법 */
    int c,a=n,b=m;
    while(b != 0)
    {
        c = a % b;
        a = b;
        b = c;
    }
    answer.push_back(a);
    // 나오는 a값이 최대공약수이다 (유클리드 호제법)
    answer.push_back(n*m/a);
    return answer;
}
/* 유클리드 호제법 재귀 구현 */
int GCD(int a, int b)
{
  if(a == 0) return b;
  return GCD(b%a, a);
}
/* 최소공배수 */
int LCM(int a, int b)
{
  return a*b / GCD(a,b);
}

[ 10. accumulate (요소 합 구하기) ]

: stl 자료구조 요소들의 합을 구할 수 있다.
<numeric>헤더에 있는 accumulate() 이용!

  /* 3번째 인자는 sum의 초기값으로 사용 */
  double answer = accumulate(arr.begin(), arr.end(), 0);
  return answer/(double)arr.size();

[ 11. resize / reserve ]

: vector와 같은 자료구조를 선언한 뒤 크기를 지정하지 않으면 인덱스로 접근할 수 없다 !(당연!)
   --> 이 때 resize()로 미리 일정 크기만큼 원하는 값으로 초기화 할 수 있다.

  • resize() : 원하는 크기 / 초기값을 입력해서 초기화하고 생성해준다!!

  • reserve() : 메모리를 예약할 뿐 초기화 / 생성하지는 않는다!

    vector<vector<int>> solution(vector<vector<int>> arr1, vector<vector<int>> arr2) {
      vector<vector<int>> answer;
      for(int i=0;i<arr1.size();i++)
      {
         /* 미리 사이즈만큼 만들어서 default인 0으로 초기화 */
          answer.resize(arr1.size());
          for(int j=0;j<arr1[i].size();j++)
          {
            /* 미리 사이즈만큼 만들어서 default인 0으로 초기화 */
              answer[i].resize(arr1[i].size());
              answer[i][j]=arr1[i][j] + arr2[i][j];
          }
      }
      return answer;
    }

  • 추가적으로 resize()한 뒤 이미 default값으로 채워져 있는데
    이 곳에 push_back()으로 값을 넣으면 안됨!! (바보같은 행동!)
    --> 인덱스로 접근해서 사용하도록~

[ 12. 이진화 연산 ( | 와 >> ) ]

: 이진화와 관련된 연산을 할 때 | (OR)연산과 >> (시프트)연산이 유용하게 쓰일 수 있다.

/* 이진화 할 때 '>>' 연산을 하면 쉽다 */
  int N = 8;
  int a , b;
  while(N != 0)
  {
      a = N % 2;
      N = N >> 1;
      cout << a ; // 2진화 한 값들이 거꾸로 출력되는것 주의!
  }

[ 13. 확률 구할때 double형변환 처리 ]

: 확률을 구하는 과정에서 소수점이 발생하는데 꼭 가끔 형변환 처리를 안해줘서 원하는 값이 안나오곤 했다.

int sum = 36542;
double avg = sum / (double)5;

[ 14. sstream (원하는 문자 꺼내기) ]

: 입력받은 문자열 중에서 원하는 자료형의 값을 빼낼 수 있다! (신기)
   담는 데이터 형에 따라 값을 추출할 수 있다!

#include <sstream>

int score;

	/* sstream 초기화 */
방법 1) stringstream ss("25T32S");
방법 2) string str = "25T32S";
     ss.str(str);

     /* 값 추출 */
ss >> score; // score가 int형이기 때문에 25를 가져온다.
ss.get(); // T를 가져온다.
ss >> score; // score가 int형이기 때문에 32를 가져온다.
ss.get(); // S를 가져온다.
ss.unget(); // S를 다시 ss에 넣는다

[ 15. erase() 주의 ]

: vector.erase()의 반환 값은 삭제된 후 다음요소를 가리키는 iterator이다.
   --> 만약 삭제 후 요소의 변화가 영향을 준다면 감소처리를 할 때도 있음

  /* 여분의 체육복이 있는데, 도난당한 학생을 제외하하여 순수 lost / reserve만 남기는 코드 */
  for(auto a = lost.begin(); a!= lost.end();a++){
      auto it = find(reserve.begin(), reserve.end(), *a);
      if(it != reserve.end()){
          reserve.erase(it);
          /* erase한 후 반환값은 다음 요소를 가리키는 iterator */
          a = lost.erase(a);
          a--;
      }
  }
profile
Developer & PhotoGrapher

0개의 댓글