분류
C++
[과제]C++ 기말 과제물 - 2020
컨텐츠 정보
- 조회 9,488
본문
1번
Person.h
#ifndef PERSON_H_INCLUDED
#define PERSON_H_INCLUDED
class Person {private:char* name;char* addr;
public:// 디폴트 생성자Person();
// 사용자 생성자
Person(const char* name, const char* addr);
// 복사 생성자
Person(const Person& c);
// 이동 생성자
Person(Person&& c) noexcept;
// 대입 연산자
Person& operator=(const Person& p);
// 이동 대입 연산자
Person& operator=(Person&& p) noexcept;
~Person();
void print() const;
void chAddr(const char* newAddr);
};
#endif
Person.cpp
#include
#include
#include
#include
#include "Person.h"
using namespace std;
#pragma warning(disable:4996)
Person::Person()
{
this->name = NULL;
this->addr = NULL;
cout << "Person 객체 생성함(" << name << ")" << endl;
}
Person::Person(const char* name, const char* addr)
{
this->name = new char[strlen(name) + 1];
strcpy(this->name, name);
this->addr = new char[strlen(addr) + 1];
strcpy(this->addr, addr);
cout << "Person 객체 생성함(" << name << ")" << endl;
}
Person::Person(const Person& c)
{
this->name = new char[strlen(c.name) + 1];
strcpy(this->name, c.name);
this->addr = new char[strlen(c.addr) + 1];
strcpy(this->addr, c.addr);
cout << "복사 생성자를 통하여 Person 객체 생성함(" << name << ")" << endl;
}
Person::Person(Person&& c) noexcept
{
this->name = c.name;
this->addr = c.addr;
c.name = nullptr;
c.addr = nullptr;
cout << "이동 생성자를 통하여 Person 객체 생성함(" << name << ")" << endl;
}
// 대입 연산자
Person& Person::operator=(const Person& p)
{
if (name != NULL || addr != NULL)
{
if (name != NULL)
{
delete[] name;
}
if (addr != NULL)
{
delete[] addr;
}
cout << "대입 연산자에 의해 메모리가 해제 되었음" << endl;
}
name = new char[strlen(p.name) + 1];
strcpy(name, p.name);
addr = new char[strlen(p.addr) + 1];
strcpy(addr, p.addr);
return *this;
}
// 이동 대입 연산자
Person& Person::operator=(Person&& p) noexcept
{
if (name != NULL || addr != NULL)
{
if (name != NULL)
{
delete[] name;
}
if (addr != NULL)
{
delete[] addr;
}
cout << "이동 대입 연산자에 의해 메모리가 해제 되었음" << endl;
}
name = p.name;
addr = p.addr;
p.name = nullptr;
p.addr = nullptr;
return *this;
}
Person::~Person()
{
if (name == NULL && addr == NULL)
{
cout << "이동 된 Person 객체 메모리 해제 없이 제거함" << endl;
}
if (name != NULL) {
cout << "Person 객체 제거함(" << name << ")" << endl;
delete[] name;
}
if (addr != NULL) {
delete[] addr;
}
}
void Person::print() const
{
cout << addr << "에 사는 " << name << " 입니다." << endl;
}
void Person::chAddr(const char* newAddr)
{
delete[] addr;
addr = new char[strlen(newAddr) + 1];
strcpy(addr, newAddr);
}
#include <iostream>
#include <vector>
#include <cstring>
#include <ctime>
#include "Person.h"
using namespace std;
#pragma warning(disable:4996)
Person::Person()
{
this->name = NULL;
this->addr = NULL;
cout << "Person 객체 생성함(" << name << ")" << endl;
}
Person::Person(const char* name, const char* addr)
{
this->name = new char[strlen(name) + 1];
strcpy(this->name, name);
this->addr = new char[strlen(addr) + 1];
strcpy(this->addr, addr);
cout << "Person 객체 생성함(" << name << ")" << endl;
}
Person::Person(const Person& c)
{
this->name = new char[strlen(c.name) + 1];
strcpy(this->name, c.name);
this->addr = new char[strlen(c.addr) + 1];
strcpy(this->addr, c.addr);
cout << "복사 생성자를 통하여 Person 객체 생성함(" << name << ")" << endl;
}
Person::Person(Person&& c) noexcept
{
this->name = c.name;
this->addr = c.addr;
c.name = nullptr;
c.addr = nullptr;
cout << "이동 생성자를 통하여 Person 객체 생성함(" << name << ")" << endl;
}
// 대입 연산자
Person& Person::operator=(const Person& p)
{
if (name != NULL || addr != NULL)
{
if (name != NULL)
{
delete[] name;
}
if (addr != NULL)
{
delete[] addr;
}
cout << "대입 연산자에 의해 메모리가 해제 되었음" << endl;
}
name = new char[strlen(p.name) + 1];
strcpy(name, p.name);
addr = new char[strlen(p.addr) + 1];
strcpy(addr, p.addr);
return *this;
}
// 이동 대입 연산자
Person& Person::operator=(Person&& p) noexcept
{
if (name != NULL || addr != NULL)
{
if (name != NULL)
{
delete[] name;
}
if (addr != NULL)
{
delete[] addr;
}
cout << "이동 대입 연산자에 의해 메모리가 해제 되었음" << endl;
}
name = p.name;
addr = p.addr;
p.name = nullptr;
p.addr = nullptr;
return *this;
}
Person::~Person()
{
if (name == NULL && addr == NULL)
{
cout << "이동 된 Person 객체 메모리 해제 없이 제거함" << endl;
}
if (name != NULL) {
cout << "Person 객체 제거함(" << name << ")" << endl;
delete[] name;
}
if (addr != NULL) {
delete[] addr;
}
}
void Person::print() const
{
cout << addr << "에 사는 " << name << " 입니다." << endl;
}
void Person::chAddr(const char* newAddr)
{
delete[] addr;
addr = new char[strlen(newAddr) + 1];
strcpy(addr, newAddr);
}
3번
3. 교재의 [소스코드 7-11]을 수정하여 [소스코드 5-6, 5-7]의 Complex2 객체의 배열에 대해 rPart의 제곱과 iPart의 제곱의 합을 기준으로 내림차순 정렬 및 합병을 하려고 한다. [소스코드 7-11]을 어떻게 수정해야 하는지 설명하고, 이 방법에 따라 프로그램을 수정하라. (20점)
#include <iostream>
#include <vector>
#include <ctime>
#include "Complex2.h"
using namespace std;
template <typename T> class GREATER
{
public:
bool operator()(const T &t1, const T &t2) const
{
return pow(t1.real(), 2) + pow(t1.imag(), 2) > pow(t2.real(), 2) + pow(t2.imag(), 2);
}
};
int main()
{
srand((unsigned)time(NULL)); // 난수 발생기 초기화
vector<Complex2> vector1;
for (int i = 0; i < 5; i++)
{
vector1.push_back(Complex2(rand() % 101-50, rand() % 100));
}
sort(vector1.begin(), vector1.end(), GREATER<Complex2>()); // 정렬 알고리즘
cout << "정렬된 백터 1: ";
for (auto i : vector1)
cout << i << " ";
vector<Complex2> vector2 ;
for (int i = 0; i < 5; i++)
{
vector2.push_back(Complex2(rand() % 101 - 50, rand() % 100));
}
//
sort(vector2.begin(), vector2.end(), GREATER<Complex2>()); // 정렬 알고리즘
cout << endl << "정렬된 벡터 2 : ";
for (auto i : vector2)
cout << i << " ";
cout << endl
<< endl;
// 합병 결과를 저장할 백터
vector<Complex2> vector3(vector1.size() + vector2.size());
// vector1과 vector2를 합병한 결과를 vector3에 저장
merge(vector1.begin(), vector1.end(), vector2.begin(), vector2.end(), vector3.begin()
, GREATER<Complex2>());
cout << "합병된 백터 3 ";
for (auto i : vector3)
cout << i << " ";
cout << endl
<< endl;
return 0;
}
설명 (박명철 교수님)
먼저, Complex2 배열 객체를 생성하는 방법입니다.
원 소스에서 요구된 백터를 이용한 배열 객체를 생성은 다음과 같이 하면 될 것 같습니다
vector <Complex2> a;
백터는 일종의 배열의 확장이라고 보시면 됩니다.
단순한 기억 장소외에 반복자나 알고리즘(기능적 메소드)등을 가지는 라이브러리입니다.
위와 같이 Complex2 타입의 백터 객체를 선언하고..
아래와 같이 반복문을 수행하면서 벡터의 마지막에 생성된 객체를 추가하면 됩니다.
srand((snsigned)time(NULL));
for ( int i =0; i < 5; i++) {
a.push_back(Complex2(rand() & 100, rand() % 100));
cout << a[i] << “ “ ;
}
난수 발생을 위한 초기화를 한 이후에
a 벡터에 요소를 추가할때 (push_back)
Complex2 생성자가 수행되도록 하면 됩니다. 이때 전달되는 인수를 실수부와 허수부의 난수를 전달하면 되겠죠..
위 코드만 수행해도 Complex2 객체의 배열이 생성되고 추력되는 것을 확인할 수 있습니다.
그 다음이 내림차순 정렬입니다.
Complex2 클래스는 별도의 관계 연산자가 없습니다.
그래서 sort알고리즘은 형식2를 사용해야 합ㄴ다.
sort(a.begin(), a.end());
이렇게 하면 정렬은 되는 오름차순 정렬이 됩니다.
내림차순 정렬은 위해서는 콜백함수를 정의하고 지정해야 합니다.
첫번째 방법은
bool comp(const Complex2 &t1, const Complex2 &t2) {
retrun pos(t1.real(), 2) + pow(t1.imag(), 2) > pow(t2.read(), 2) + pow(t2.imag(), 2);
}
상단에 이렇게 비교를 위한 함수를 정의힙니다
문제에서 실수부와 허수부의 제곱의 합을 내림차눗으로 한다고 했으니
pow함수를 사용하여 제곱하고 더한 결과를 비교합니다
부등호가 > 내림차순, < 오름차순입니다.
그리고 하단 sort 에서는 다음과 같이 콜백함수를 지정만 하면 됩니다.
sort(a.begin(), a.end(), comp);
cout<< endl << “정렬된 백터a : “;
for (auto i : a) {
cout << i << ““;
}
범위 지정 for문을 이용하여 a 백터의 범위만큼 반복하면서 출력합니다.
출력의 형식은 이미 Complex2 클래스의 메소드에 정의 되어 있기 떄문에 별도 작업이 필요 없습니다.
두번째 방법은 함수 객체를 이용하는 방법입니다.(교재에서 언급)
template<typename T> class GREATER {
pubilc:
bool operator()(const T& t1, cont T& t2) const {
retrun pos(t1.real(), 2) + pow(t1.imag(), 2) > pow(t2.read(), 2) + pow(t2.imag(), 2);
}
};
상단의 함수 객체를 정의하고
하단에서 다음과 같이
sort(a.begin(), a.end(), GREATER<Complex2>());
cout << endl < “정렬된 백터 a :“
for (auto i:a){
cout << i << ““;
}
두 방법중에 하나를 사용하시면 되 듯 합니다.
더 자세한 코드는 과제물이 기말고사 평정이라 제가 기술하기에는 불편함이 있습니다.
혹 어려워 포기하는 분들을 위해 힌트를 드립니다.
끝까지 최선을…
방송대 단톡 C 님 풀이
Complex2에 conj()가 켤레복소수를 반환하는데 이를 이용하면 더 깔끔하게 작성할 수 있습니다.
이런식으로 하면 <int>를 <Complex2>로 수정하는 부분을 제외하고 거의 수정하지 않고 3번문제를 해결 할 수 있습니다.
관련자료
-
서명방송통신대학교 컴퓨터 과학과 단톡 https://open.kakao.com/o/gSLabj6 온라인으로 유학하는 사람들 https://ongongsa.com
댓글 0개
등록된 댓글이 없습니다.