#include <ssteram>
using namespace std;

string str = "find new";
stringstream in(str);
string a, b;
in >> a >> b;

// a = "find"
// b = "new"

활용시 참고

https://life-with-coding.tistory.com/403

 

[C++] stringstream 사용법

인트로 안녕하세요. 오늘은 C++의 Stringstream 사용법에 대해 포스팅하겠습니다. C++에서 여러가지 자료형이 한 줄에 들어오면 파싱해서 용도에 맞게 사용할 필요가 있는데요. 특히 "이름 날짜 내용"

life-with-coding.tistory.com

 

https://notepad96.tistory.com/57

 

C++ min, max 함수

1. min, max, minmax min, max, minmax는 algorithm 라이브러리의 구현되어 있는 함수이다. 각 함수들은 두 값을 비교하여 더 작은 값, 더 큰 값을 반환해 준다. 위 함수는보통 2개의 값만 비교하여 최대값, 최

notepad96.tistory.com

https://notepad96.tistory.com/40

 

C++ Vector 최대값, 최소값, 인덱스 구하기

1. 최대값, 최소값 vector 컨테이너에서 최대값, 최소값을 구할 경우 for문을 작성할 수도 있지만 이는 복잡하다. 그래서 algorithm 라이브러리의 있는 max_element를 사용한다면 한줄로도 간단하게 최대

notepad96.tistory.com

 

#include <stirng>

int a = std::stoi("1");        // string to int
int b = '7' - '0';             // char   to int
string c = std::to_string(3);  // int    to string
char ch = (char)(9 + 48);      // int    to char

ASCII 코드에서 숫자 0은 48부터 시작하기 때문

#include <vector>
#include <unordered_map>
#include <algorithm>
#include <iostream>
using namespace std;

bool cmp(pair<string, int>& a, pair<string, int>& b)
{
    return a.second < b.second;
}

int main()
{
    unordered_map<string, int> map;

    map["a"] = 6;
    map["b"] = 1;
    map["c"] = 4;
    map["d"] = 8;

    vector<pair<string, int>> vec(map.begin(), map.end()); // map을 vector로 변경
    sort(vec.begin(), vec.end(), cmp);

    for (auto elem : vec)
    {
        cout << elem.first << endl;
    }
}

출력 결과

b
c
a
d
C++를 언어들의 연합체로 바라보는 안목은 필수

▶ C

  • C++은 C를 기본으로 함

▶ 객체 지향 개념의 C+

  • 'C with Classes'에 관한 모든 것
  • 클래스(Class), 캡슐화(Encapsulation), 상속(Inheritance), 다형성(Polymorphism). 가상 함수(Virtual function)
    • 정적 바인딩: 컴파일시에 메모리를 할당 >> 일반 함수, 일반 변수 할당
    • 동적 바인딩: 런타임시에 메모리를 할당 >> 가상 함수, 변수 동적 할당
  • https://simsimjae.tistory.com/293

▶ 템플릿 C++

  • C++ 일반화 프로그래밍(Generic programming)의 일부

▶ STL

  • Standard Template Library
이것만은 잊지 말자! 
C++를 사용한 효과적인 프로그래밍 규칙은 경우에 따라 달라진다. 그 경우란, 바로 C++의 어떤 부분을 사용하느냐이다.

#define을 쓰려거든 const, enum, inline을 떠올리자

▶ #define

#define ASPECT_RATIO 1.653
  • 컴파일 전에 선행 처리자(Preprocessor)가 ASPECT_RATIO를 찾아 1.653으로 치환함
  • 따라서 컴파일러는 이것이 ASPECT_RATIO라는 것을 알 수 없음
  • 디버깅에 혼란이 올 수 있음

▶ const

const double AspectRatio = 1.653;
  • 위 문제의 해결법은 매크로 대신 상수를 쓰는 것

▶ #define을 상수로 교체할 때 주의점

  • 상수 포인터(constant pointer) 정의
    • 상수 정의는 대게 헤더 파일에 넣어 다른 파일들이 include해서 사용
    • 포인터는 const로 선언하고, 포인터가 가리키는 대상까지 const로 선언
const char* const authorName = "Scott Meyers";
  • 클래스 상수 정의
    • 클래스 상수의 사본 개수가 1개를 넘지 못하게 하고 싶다면 정적(static) 멤버로 선언
    • #define과 달리 클래스 상수는 캡슐화 혜택을 받을 수 있음
    • 오래된 컴파일러는 아래 문법을 받아들이지 못하는 경우가 있으므로, 초기값을 상수 정의시 지정
class GamePlayer{
private:
   static const int NumTurns = 5;   // 클래스 상수 선언과 동시에 초기화
}
// 오래된 컴파일러
class GamePlayer{
private:
   static const int NumTurns;        // 정적 클래스 상수 선언, 헤더파일
}

const int GamePlayer::NumTurns = 5;  // 정적 클래스 상수 정의, 구현 파일

▶ enum

  • 컴파일러가 구식인데 클래스를 컴파일하는 도중에 클래스 상수가 필요할 때 사용
  • 'enum hack' 기법
  • #define처럼 주소를 얻어갈 수 없음
class GamePlayer {
private:
   enum { NumTurns = 5 };
   int scores[NumTurns];
}

 

 

▶ 매크로 함수

  • #define을 이용한 매크로 함수는 단점이 많음
  • 아래의 경우 비교를 통해 처리한 결과에 따라 a가 증가하는 횟수가 달라짐
#define CALL_WITH_MAX(a, b) f((a) > (b) ? (a) : (b))

int a= 5, b = 0;
CALL_WITH_MAX(++a, b);      // a가 두 번 증가
CALL_WITH_MAX(++a, b+10);   // a가 한 번 증가
  • CALL_WITH_MAX(++x, y) → ((++x) > (y) ? (++x) : (y)): 비교할 때 1번, return 할 때 1번 총 2번 증가
  • CALL_WITH_MAX(++x, y + 10) ((++x) > (y + 10) ? (++x) : (y + 10)): 비교할 때 1번 증가

▶ inline

  • 매크로 함수의 문제점에 대한 해결법
  • 일반적인 함수 호출 과정을 거치지 않고, 함수의 모든 코드를 호출된 자리에 바로 삽입하는 방식
  • 함수를 호출하데 걸리는 시간이 절약됨
template<typename T>
inline void callWithMax(const T& a, const T& b)
{
   f(a > b ? a : b);
}
이것만은 잊지 말자! 
단순한 상수를 쓸 때는, #define보다 const 객체 혹은 enum을 우선 생각하자
함수처럼 쓰이는 매크로를 만들려면, #define 매크로보다 인라인 함수를 우선 생각하자

낌새만 보이면 const를 들이대 보자!
  • 값을 바꾸면 안된다면 명시적으로 const를 사용
char greeting[] = "Hello";
const char *p = greeting;   // 비상수 포인터, 상수 데이터
char * const p = greeting;  // 상수 포인터, 비상수 데이터
  • 아래 두 코드는 완전히 동일
void f1(const Widget *pw);
void f2(Widget const *pw);
  • 선언(declaration)은 코드에 사용 되는 '어떤 대상'의 이름과 타입을 컴파일러에게 알려주는 것 
extern int x;                        // 객체 선언
std::size_t numDigits(int number)    // 함수 선언

extern

  • 외부 참조 지정자
  • 다른 모듈에 존재하는 변수를 전역 변수처럼 사용하기 위해 사용함
  • extern을 이용해 외부 모듈 어딘가 변수나 함수가 선언되어 있다고 정보를 알려줌으로써 컴파일시에 식별자를 찾지 못한다는 에러를 일으키지 않음
  • 링크 과정에서 결정
  • https://thrillfighter.tistory.com/397

▶ std::size_t

  • typedef unsigned int size_t
  • C++에서 개수를 셀 때 주로 사용

  • 정의(definition)은 선언에서 빠진 구체적인 세부사항을 컴파일러에 제공하는 것
int x;                             // 객체 정의
std::size_t numDigits(int number)  // 함수 정의
{
    std::size_t digit = 1;
    return digit;
}
  • 객체의 경우는 컴파일러가 그 객체에 대한 메모리를 마련해 놓은 부분이 정의가 됨

  • 초기화(initialization)는 어떤 객체에 최초의 값을 부여하는 과정
    •   사용자 정의 타입으로 생성된 경우, 초기화는 생성자에 의해 이루어짐
Class Widget {
public:
    Widget();                              // 기본 생성자(defulat constructor)
    Widget(const Widget& rhs);             // 복사 생성자(copy constructor)
    Widget& operator=(const Widget& rhs);  // 복사 대입 연산자(copy assignment operator)
}

Widget w1;                                 // 기본 생성자 호출
Widget w2(w1);                             // 복사 생성자 호출
w1= w2;                                    // 복사 대입 연산자 호출
Widge w3 = w2;                             // 복사 생성자 호출
  • lhs - light hand side / rhs - right hand side
bool hasAcceptableQuality(Widget w);

Widget aWidget;
if (hasAcceptableQuality(aWidget))     // 복사 생성자 호출
  • 함수 호출 시 aWidget는 복사 생성자를 통해 w로 복사됨
  • 즉 'pass-by-value'는 '복사 생성자 호출'

  • 명시적 타입 변환(explicit type casting)은 캐스팅할 type 명시
  • 암시적 타입 변환(implicit type casting)은 캐스팅할 type을 컴파일러가 알아서 지정
// Implicit conversion
int i = 75;
long j = i;

// Explicit conversion
double d = 75.25;
int i = (int)d;
class A
{
public:
    explicit B(int x = 0, bool b = true);  // 기본 생성자(default constructor)
};
  • 클래스의 생성자에선 특별한 경우가 아니면 explicit을 통해 의도치 않은 암시적 변환을 막아주는 것이 좋음

  • 표기법

▶ Camel Case

int helloWorld;
  • 첫 글자는 소문자, 두 번째 단어부터는 첫 글자 대문자
  • Java 프로그래밍에서 권장

Pascal Case

int HelloWorld;
  • 첫 글자와 단어의 첫 글자 대문자
  • Python 프로그래밍에서 권장

▶ Snake Case

int hello_world;
  • 단어 사이를 언더바로 연결

▶ Hungarian Notation

bool bInitialized = false;
int nSize = 2;
Widget* pWidget;

  • 16진수(Hexadecimal)
    • 16진법에서는 숫자 0~9까지와 영문 알파벳 문자 A~F까지를 사용함
    • 16진수는 근대 컴퓨터에 1 byte를 8 bit로 정의되어 있기 때문에 2진수를 표현하는 편리한 방법
    • 한 개의 16진수 숫자는 4개의 2진수 숫자를 표시할 수 있음, 두 개의 16진수 숫자는 8bit, 즉 1 byte를 표현할 수 있음
2진수 10진수 16진수
0 0 0
1 1 1
10 2 2
11 3 3
100 4 4
101 5 5
110 6 6
111 7 7
1000 8 8
1001 9 9
1010 10 A
1011 11 B
1100 12 C
1101 13 D
1110 14 E
1111 15 F
10000 16 10
10001 17 11

 


  • Build 과정
    • Build = Compile + Link
    • Run = Build + 실행

▶ Compile

  • Compile은 High-level language(Python, C)인 소스 코드를 Low-level language(기계어, 어셈블리어)로 번역하는 과정
  • 결과로 목적 파일(.obj)이 생성됨

▶ Link

  • 여러 개의 목적 파일을 합쳐서 하나의 실행 가능한 파일로 만드는 과정
  • 결과로 실행 파일(.exe)이 생성됨
  • Static link: 컴파일된 소스 파일들을 연결해서 최종 실행 가능한 파일을 생성
  • Dynamic link: 프로그램 실행 도중, 프로그램 외부에 존재하는 코드(.dll)를 찾아서 연결, 링커가 필요 없음
  • https://jhnyang.tistory.com/42
  • https://jhnyang.tistory.com/40

 

#include <iostream>
#include <queue>
using namespace std;

struct cmp {
	bool is_int(char a) {
		int code = (int)a;
		return a >= 48 && a <= 57; // 아스키코드
	}

	// true면 a와b가 위치를 swap
	bool operator()(string a, string b) {
		if (a.length() != b.length()) // 길이가 다르면 짧은 것이 먼저온다.
			return a.length() > b.length();

		// 길이가 같다면
		int sumA = 0, sumB = 0;
		for (int i = 0; i < a.length(); i++){
			if (is_int(a[i])) sumA += (a[i] - '0');
			if (is_int(b[i])) sumB += (b[i] - '0');
		}
		if (sumA != sumB)
			return sumA > sumB; // 각 자리수의 숫자의 합이 작은 것이 먼저온다

		// 숫자의 합이 같다면 사전순
		for (int i = 0; i < a.length(); i++) {
			return (int)a[i] > (int)b[i];
		}

		return true;
	}
};

int main()
{
	priority_queue<int, vector<int>, greater<int>> minHeap; // 최소힙
    
    priority_queue<int, vector<int>, less<int>> minHeap; // 최대힙

	priority_queue<string, vector<string>, cmp> myQ; // 커스텀
}

twpower.github.io/93-how-to-use-priority_queue-in-cpp

 

[C++] C++ STL priority_queue 기본 사용법과 예제

Practice makes perfect!

twpower.github.io

 

#include <set>
using namespace std;

int main()
{
	// 집합 선언
	set<int> s;

	// element 추가 (default 오름차순 정렬)
	s.insert(elem);
}

www.cplusplus.com/reference/set/set/

 

set - C++ Reference

difference_typea signed integral type, identical to: iterator_traits ::difference_type usually the same as ptrdiff_t

www.cplusplus.com

 

+ Recent posts