문제(문자열을 정수로 바꾸기)
https://school.programmers.co.kr/learn/courses/30/lessons/12925
제출한 답안
#include <string>
#include <vector>
using namespace std;
int solution(string s) {
int answer = 0;
answer = stoi(s);
return answer;
}
stoi라고 문자열을 정수로 변환해주는 함수가 있었다. 그 외에도 다른 자료형으로 변환해주는 함수들이 있다.(string 포함시키기)
문제(정수 제곱근 판별)
https://school.programmers.co.kr/learn/courses/30/lessons/12934
제출한 답안
#include <string>
#include <vector>
#include <cmath>
#include <iostream>
using namespace std;
long long solution(long long n) {
long long answer = -1;
double x = sqrt(n);
double divide = 0.0;
double remainder = modf(x, ÷);
if (remainder == 0.0)
{
answer = pow(x+1, 2);
}
return answer;
}
modf함수는 들어온 숫자의 정수부분과 소수점부분을 나눠주는 함수이다. 소수점부분이 반환값이고 두번째 인수가 정수부분을 저장할 수 있는 주소값이다. sqrt는 제곱근 구하는 함수, pow는 base숫자를 n제곱 해주는 함수이다. (sqrt와 pow는 cmath, modf는 iostream 포함시키기)
문제(정수 내림차순으로 배치하기)
https://school.programmers.co.kr/learn/courses/30/lessons/12933
제출한 답안
#include <string>
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
bool compare(int& a, int& b)
{
return a > b;
}
long long solution(long long n) {
long long answer = 0;
vector<int> digits{};
while (n != 0)
{
digits.push_back(n % 10);
n /= 10;
}
sort(digits.begin(), digits.end(), compare);
for (vector<int>::iterator iter = digits.begin(); iter != digits.end(); iter++)
{
answer = answer * 10 + *iter;
}
return answer;
}
배열의 각각 요소들을 자릿값으로 삼아 하나의 정수로 나타낼 때 for문 안에 있는 식을 사용하면 좋다.(answer +=으로 쓰지 않도록 하자. 잘 몰라서 삽질했다;;)
디자인 패턴
디자인 패턴에는 생성 패턴, 구조 패턴, 행동 패턴이 있다.(각각 1개씩 배운다.)
싱글톤 패턴(생성 패턴)
프로그램 진행 내내 오직 하나의 객체만 존재 한다. 변수를 다르게 잡고 사용한 것처럼 보여도 실은 하나의 객체에서 실행 된다.
(생성자는 private, 복사생성자, 대입연산자는 delete, 멤버 변수와 getInstance 함수를 static으로 만들기, 함수 내용은 멤버 변수가 nullptr이면 동적 할당 해주고 반환)
데코레이터 패턴(구조 패턴)
#include <iostream>
#include <string>
using namespace std;
// **추상 컴포넌트 (Component): Pizza**
// - 피자 객체의 기본 구조를 정의하는 인터페이스입니다.
// - 모든 피자는 이름(`getName`)과 가격(`getPrice`)을 가져야 합니다.
class Pizza {
public:
virtual ~Pizza() {}
virtual string getName() const = 0; // 피자의 이름 반환
virtual double getPrice() const = 0; // 피자의 가격 반환
};
// **구체 컴포넌트 (Concrete Component): BasicPizza**
// - 기본 피자 클래스입니다.
// - 피자의 기본 베이스(이름과 가격)를 구현합니다.
class BasicPizza : public Pizza {
public:
string getName() const {
return "Basic Pizza"; // 기본 피자의 이름
}
double getPrice() const {
return 5.0; // 기본 피자의 가격
}
};
// **데코레이터 추상 클래스 (Decorator): PizzaDecorator**
// - 기존 피자의 기능을 확장하기 위한 데코레이터의 기본 구조를 정의합니다.
// - 내부적으로 `Pizza` 객체를 감싸며, 이름과 가격에 추가적인 기능을 제공합니다.
class PizzaDecorator : public Pizza {
protected:
Pizza* pizza; // 기존의 피자 객체를 참조합니다.
public:
// 데코레이터는 피자 객체를 받아서 감쌉니다.
PizzaDecorator(Pizza* p) : pizza(p) {}
// 소멸자에서 내부 피자 객체를 삭제합니다.
virtual ~PizzaDecorator() {
delete pizza;
}
};
// **구체 데코레이터 (Concrete Decorators): Cheese, Pepperoni, Olive**
// - 각각의 토핑 데코레이터는 `PizzaDecorator`를 상속받아 이름과 가격을 확장합니다.
// 치즈 토핑 데코레이터
class CheeseDecorator : public PizzaDecorator {
public:
CheeseDecorator(Pizza* p) : PizzaDecorator(p) {}
string getName() const {
// 기존 피자의 이름에 " + Cheese"를 추가
return pizza->getName() + " + Cheese";
}
double getPrice() const {
// 기존 피자의 가격에 치즈 추가 비용 1.5를 더함
return pizza->getPrice() + 1.5;
}
};
// 페퍼로니 토핑 데코레이터
class PepperoniDecorator : public PizzaDecorator {
public:
PepperoniDecorator(Pizza* p) : PizzaDecorator(p) {}
string getName() const {
// 기존 피자의 이름에 " + Pepperoni"를 추가
return pizza->getName() + " + Pepperoni";
}
double getPrice() const {
// 기존 피자의 가격에 페퍼로니 추가 비용 2.0을 더함
return pizza->getPrice() + 2.0;
}
};
// 올리브 토핑 데코레이터
class OliveDecorator : public PizzaDecorator {
public:
OliveDecorator(Pizza* p) : PizzaDecorator(p) {}
string getName() const {
// 기존 피자의 이름에 " + Olive"를 추가
return pizza->getName() + " + Olive";
}
double getPrice() const {
// 기존 피자의 가격에 올리브 추가 비용 0.7을 더함
return pizza->getPrice() + 0.7;
}
};
// **클라이언트 코드**
// - 피자와 데코레이터를 조합하여 최종 피자를 생성하고, 정보를 출력합니다.
int main() {
// 1. 기본 피자를 생성합니다.
Pizza* pizza = new BasicPizza();
// 2. 치즈 토핑을 추가합니다.
pizza = new CheeseDecorator(pizza);
// 3. 페퍼로니 토핑을 추가합니다.
pizza = new PepperoniDecorator(pizza);
// 4. 올리브 토핑을 추가합니다.
pizza = new OliveDecorator(pizza);
// 5. 최종 피자 정보 출력
cout << "Pizza: " << pizza->getName() << endl; // 피자의 이름 출력
cout << "Price: $" << pizza->getPrice() << endl; // 피자의 가격 출력
// 6. 메모리 해제
delete pizza;
return 0;
}
옵저버 패턴(행동 패턴)
어떤 데이터가 변경됐을 때 그 데이터를 기반으로 만들어진 차트들이 전부 자동으로 업데이트가 되어야 한다.
Subject : 옵저버들에게 상태가 변경됐을 때마다 알려주는 역할
Observer : 서브젝트가 알려준 변경된 데이터에 따라 행동하는 역할
#include <iostream>
#include <vector>
#include <string>
using namespace std;
// Observer 인터페이스
// - Observer 패턴에서 상태 변화를 알림받는 객체들의 공통 인터페이스
// - Observer들은 이 인터페이스를 구현하여 `update` 메서드를 통해 데이터를 전달받음
class Observer {
public:
virtual ~Observer() = default; // 가상 소멸자
virtual void update(int data) = 0; // 데이터 업데이트 메서드 (순수 가상 함수)
};
// Subject 클래스 (엑셀 시트 역할)
// - 데이터의 상태 변화를 관리하며, 모든 등록된 Observer들에게 변경 사항을 알림
class ExcelSheet {
private:
vector<Observer*> observers; // Observer들을 저장하는 리스트
int data; // 현재 데이터 상태
public:
ExcelSheet() : data(0) {} // 생성자: 초기 데이터 값은 0
// Observer 등록 메서드
// - 새로운 Observer를 등록하여 변경 사항 알림을 받을 수 있도록 추가
void attach(Observer* observer) {
observers.push_back(observer);
}
// 데이터 변경 알림 메서드
// - 등록된 모든 Observer들의 `update` 메서드를 호출하여 데이터 변경 사항을 알림
void notify() {
for (Observer* observer : observers) {
observer->update(data); // 각 Observer에게 데이터를 전달
}
}
// 데이터 설정 메서드
// - 데이터를 변경하고 변경 사항을 모든 Observer에게 알림
void setData(int newData) {
data = newData; // 새로운 데이터로 갱신
cout << "ExcelSheet: Data updated to " << data << endl;
notify(); // Observer들에게 알림
}
};
// 구체적인 Observer 클래스: BarChart (막대 차트)
// - 데이터를 막대 그래프로 표현
class BarChart : public Observer {
public:
void update(int data) { // 데이터 업데이트 시 호출됨
cout << "BarChart: Displaying data as vertical bars: ";
for (int i = 0; i < data; ++i) {
cout << "|"; // 데이터 값만큼 막대 출력
}
cout << " (" << data << ")" << endl;
}
};
// 구체적인 Observer 클래스: LineChart (라인 차트)
// - 데이터를 선형 그래프로 표현
class LineChart : public Observer {
public:
void update(int data) { // 데이터 업데이트 시 호출됨
cout << "LineChart: Plotting data as a line: ";
for (int i = 0; i < data; ++i) {
cout << "-"; // 데이터 값만큼 선 출력
}
cout << " (" << data << ")" << endl;
}
};
// 구체적인 Observer 클래스: PieChart (파이 차트)
// - 데이터를 파이 그래프로 표현
class PieChart : public Observer {
public:
void update(int data) { // 데이터 업데이트 시 호출됨
cout << "PieChart: Displaying data as a pie chart slice: ";
cout << "Pie [" << data << "%]" << endl; // 데이터 값 출력 (가정: % 비율로 표현)
}
};
// 메인 함수
int main() {
// Subject 생성
ExcelSheet excelSheet; // 데이터를 관리하는 엑셀 시트 객체 생성
// Observer 객체 생성 (각 차트 객체)
BarChart* barChart = new BarChart(); // 막대 차트 생성
LineChart* lineChart = new LineChart(); // 라인 차트 생성
PieChart* pieChart = new PieChart(); // 파이 차트 생성
// Observer 등록
// - 각 차트(Observer)를 엑셀 시트(Subject)에 등록
excelSheet.attach(barChart);
excelSheet.attach(lineChart);
excelSheet.attach(pieChart);
// 데이터 변경 테스트
// - 데이터를 변경하면 등록된 모든 Observer들이 알림을 받고 화면에 갱신
excelSheet.setData(5); // 데이터 변경: 5
excelSheet.setData(10); // 데이터 변경: 10
// 메모리 해제
// - 동적 할당된 Observer(차트) 객체 삭제
delete barChart;
delete lineChart;
delete pieChart;
return 0;
}
언리얼엔진 C++에서 로그 찍는 법
UE_LOG(LogTemp, Warning, TEXT("Hello World"))
이렇게 하면 출력 로그에 로그가 나온다.(뷰포트가 아니라 컨텐츠 드로어 옆의 출력 로그에서 나온다.)
출력 로그의 필터에서 원하는 로그만 나오게 만들 수 있다.
UE_LOG(LogTemp, Warning, TEXT("Sum of Numbers : %d"), Sum)
이런식으로 뒤에 원하는 변수를 출력시킬 수 있다.
1) 카테고리
LogTemp 부분이 카테고리 부분으로 출력에서 필터로 원하는 부분만 보고 싶을 때 정해주는 것이다. 보통 LogTemp를 많이 사용 한다.
2) 심각성
Log : 일반적인 메세지, 색상 없음(검정 텍스트, 흰색 배경)
Display : 일반 정보를 강조, 파란색
Warning : 경고 메세지를 강조, 주황색 또는 노란색
Error : 문제가 되는 상황을 강조, 빨간색
Fatal : 치명적이며 이후 프로그램이 종료, 빨간색
3) 실제 출력할 내용
3인칭 프로젝트 생성 및 Gameplay Abilities 플러그인 활성화(재시작)