IT 프로그래밍/객체지향프로그래밍

객체지향프로그래밍 5 과제

기술1 2024. 6. 21. 15:21
반응형

1번 문제

#include <iostream>
#include <cstdlib>
#include <vector>
#include <ctime>
using namespace std;

class OrderedVecInt {
private:
    int capacity = 0, size = 0;
    int* arr = nullptr;

    void resize(int new_capacity) {
        int* new_arr = new int[new_capacity];
        for (int i = 0; i < size; i++) {
            new_arr[i] = arr[i];
        }
        delete[] arr;
        arr = new_arr;
        capacity = new_capacity;
    }

public:
    OrderedVecInt()
    {
        arr = new int[capacity];
    }

    ~OrderedVecInt() 
    {
        delete[] arr;
    }

    void insert(int value) 
    {
        if (size == capacity) 
        {
            if (capacity == 0) 
            {
                resize(1);
            }
            else 
            {
                resize(capacity * 2);
            }
        }

        int i = size - 1;
        while (i >= 0 && arr[i] > value) 
        {
            arr[i + 1] = arr[i];
            i--;
        }
        arr[i + 1] = value;
        size++;
    }

    bool remove_by_val(int value) 
    {
        int index = -1;
        for (int i = 0; i < size; i++) 
        {
            if (arr[i] == value) 
            {
                index = i;
                break;
            }
        }
        if (index == -1) return false;

        for (int i = index; i < size - 1; i++) 
        {
            arr[i] = arr[i + 1];
        }
        size--;
        return true;
    }

    bool remove_by_index(int index) 
    {
        if (index < 0 || index >= size) return false;

        for (int i = index; i < size - 1; i++) 
        {
            arr[i] = arr[i + 1];
        }
        size--;
        return true;
    }

    int operator[](int index) const 
    {
        if (index < 0 || index >= size) 
        {
            throw out_of_range("Index out of range");
        }
        return arr[index];
    }

    int& operator[](int index) 
    {
        if (index < 0 || index >= size) 
        {
            throw out_of_range("Index out of range");
        }
        return arr[index];
    }

    int getSize() const 
    {
        return size;
    }
};

int main() 
{
    srand((unsigned int)time(NULL));
    int n;
    OrderedVecInt vec;
    cin >> n;
    for (int i = 0; i < n; i++) 
    {
        int k = rand() % 1000;
        vec.insert(k);
    }

    for (int i = 0; i < vec.getSize(); i++)
        cout << vec[i] << " ";
    cout << endl;

    if (vec.remove_by_val(vec[2]))
        cout << "Remove done" << endl;
    else
        cout << "Remove failed" << endl;

    if (vec.remove_by_index(4))
        cout << "RemoveIndex done" << endl;
    else
        cout << "RemoveIndex failed" << endl;

    for (int i = 0; i < vec.getSize(); i++)
        vec[i] -= 10;

    for (int i = 0; i < vec.getSize(); i++)
        cout << vec[i] << " ";
    cout << endl;

    return 0;
}

private 멤버

capacity : 동적 배열의 현재 용량을 나타냅니다.

size : 저장된 요소의 개수를 나타냅니다.

arr : 동적 배열을 가리키는 포인터입니다.

resize(int new_capacity) : 동적 배열의 크기를 조정하는 함수입니다. 새 배열을 생성하고, 기존 요소를 복사한 후, 이전 배열을 삭제하고, 용량을 업데이트합니다. 

 

public 멤버

OrderedVecInt() : 생성자로, 동적 배열을 초기화합니다.

~OrderedVecInt() : 소멸자로, 할당된 메모리를 해제합니다. 

insert(int value): 값을 삽입하여 정렬된 순서를 유지합니다. 필요하면 배열의 크기를 조정합니다.

remove_by_val(int value) : 값을 찾아서 제거합니다. 성공하면 true, 실패하면 false를 반환합니다.

remove_by_index(int index): 주어진 인덱스의 값을 제거합니다. 성공하면 true, 실패하면 false를 반환합니다. 

operator[](int index) const : 인덱스를 통해 요소에 접근할 수 있도록 합니다. 

getsize() const : 저장된 요소의 개수를 반환합니다.

 

랜덤 숫자 생성

srand((unsigned int) time (NULL)) : 랜덤 숫자 생성기를 초기화합니다.

INT n을 삽입할 요소의ㅏ 개수를 나타내고 OrderedVecInt vec : OrderedVecInt를 통해 클래스의 인스턴스를 생성합니다. 

 

cin >> n으로 삽입할 요소의 개수를 입력받고 루프를 통해 n개의 랜덤 정수를 vec에 삽입합니다. 

 

1번 문제 변형

다음 OrderedVecInt 클래스는 정수 값을 동적 배열에 저장하고, 정렬된 순서로 삽입하는 기능을 가지고 있습니다. 이 클래스에는 이미 배열 크기를 동적으로 조정하고, 특정 값 또는 인덱스를 통해 요소를 제거하는 기능이 포함되어 있습니다. 이 문제에서는 OrderedVecInt 클래스에 두 가지 새로운 기능을 추가하는 코드를 작성하시오.

 

기능 1: bool contains(int value) 메서드를 추가하시오. 이 메서드는 배열에 주어진 값이 포함되어 있는지 여부를 반환합니다. 값이 존재하면 true, 존재하지 않으면 false를 반환합니다.
기능 2: void clear() 메서드를 추가하시오. 이 메서드는 배열의 모든 요소를 제거하고, 배열을 초기 상태로 되돌립니다.

#include <iostream>
#include <cstdlib>
#include <vector>
#include <ctime>
using namespace std;

class OrderedVecInt {
private:
    int capacity = 0, size = 0;
    int* arr = nullptr;
    void resize(int new_capacity) {
        int* new_arr = new int[new_capacity];
        for (int i = 0; i < size; i++) {
            new_arr[i] = arr[i];
        }
        delete[] arr;
        arr = new_arr;
        capacity = new_capacity;
    }

public:
    OrderedVecInt() {
        arr = new int[capacity];
    }
    ~OrderedVecInt() {
        delete[] arr;
    }
    void insert(int value) {
        if (size == capacity) {
            if (capacity == 0) {
                resize(1);
            } else {
                resize(capacity * 2);
            }
        }
        int i = size - 1;
        while (i >= 0 && arr[i] > value) {
            arr[i + 1] = arr[i];
            i--;
        }
        arr[i + 1] = value;
        size++;
    }
    bool remove_by_val(int value) {
        int index = -1;
        for (int i = 0; i < size; i++) {
            if (arr[i] == value) {
                index = i;
                break;
            }
        }
        if (index == -1) return false;
        for (int i = index; i < size - 1; i++) {
            arr[i] = arr[i + 1];
        }
        size--;
        return true;
    }
    bool remove_by_index(int index) {
        if (index < 0 || index >= size) return false;
        for (int i = index; i < size - 1; i++) {
            arr[i] = arr[i + 1];
        }
        size--;
        return true;
    }
    int operator[](int index) const {
        if (index < 0 || index >= size) {
            throw out_of_range("Index out of range");
        }
        return arr[index];
    }
    int& operator[](int index) {
        if (index < 0 || index >= size) {
            throw out_of_range("Index out of range");
        }
        return arr[index];
    }
    int getSize() const {
        return size;
    }

    // contains 함수 추가
    bool contains(int value) {
        for (int i = 0; i < size; i++) {
            if (arr[i] == value) {
                return true;
            }
        }
        return false;
    }

    // clear 함수 추가
    void clear() {
        delete[] arr;
        arr = new int[capacity];
        size = 0;
        capacity = 0;
    }
};

int main() {
    srand((unsigned int)time(NULL));
    OrderedVecInt vec;
    vec.insert(10);
    vec.insert(20);
    vec.insert(30);
    cout << "Contains 20: " << (vec.contains(20) ? "Yes" : "No") << endl;
    vec.clear();
    cout << "Size after clear: " << vec.getSize() << endl;
    return 0;
}

 

2번 문제

#include <iostream>
#include <fstream>
#include <vector>
#include <cmath>
#include <algorithm>
#include <memory>

using namespace std;

class Circle;

class Shape {
public:
    virtual double area() const = 0;
    virtual bool intersects(const Shape& other) const = 0;
    virtual void print() const = 0;
    virtual ~Shape() = default;
};

class Rect : public Shape 
{
private:
    int xmin, xmax, ymin, ymax;
public:
    Rect(int xmin, int xmax, int ymin, int ymax) 
        : xmin(xmin), xmax(xmax), ymin(ymin), ymax(ymax) 
    {}

    double area() const override
    {
        return (xmax - xmin) * (ymax - ymin);
    }

    bool intersects(const Shape& other) const override;

    bool intersects(const Rect& other) const 
    {
        return !(xmax < other.xmin || xmin > other.xmax || ymax < other.ymin || ymin > other.ymax);
    }

    bool intersects(const Circle& other) const;

    void print() const override 
    {
        cout << "R " << xmin << " " << xmax << " " << ymin << " " << ymax << endl;
    }

    friend class Circle;
};

class Circle : public Shape 
{
private:
    int x, y, r;
public:
    Circle(int x, int y, int r) 
        : x(x), y(y), r(r) 
    {}

    double area() const override 
    {
        return 3.14 * r * r;
    }

    bool intersects(const Shape& other) const override;

    bool intersects(const Rect& rect) const 
    {
        int nearestX = max(rect.xmin, min(x, rect.xmax));
        int nearestY = max(rect.ymin, min(y, rect.ymax));
        int deltaX = x - nearestX;
        int deltaY = y - nearestY;
        return (deltaX * deltaX + deltaY * deltaY) <= (r * r);
    }

    bool intersects(const Circle& other) const 
    {
        int dx = x - other.x;
        int dy = y - other.y;
        double distance = sqrt(dx * dx + dy * dy);
        return distance <= (r + other.r);
    }

    void print() const override 
    {
        cout << "C " << x << " " << y << " " << r << endl;
    }
};

bool Rect::intersects(const Shape& other) const 
{
    const Rect* r = dynamic_cast<const Rect*>(&other);
    if (r) return intersects(*r);

    const Circle* c = dynamic_cast<const Circle*>(&other);
    if (c) return intersects(*c);

    return false;
}

bool Rect::intersects(const Circle& other) const 
{
    return other.intersects(*this);
}

bool Circle::intersects(const Shape& other) const 
{
    const Circle* c = dynamic_cast<const Circle*>(&other);
    if (c) return intersects(*c);

    const Rect* r = dynamic_cast<const Rect*>(&other);
    if (r) return intersects(*r);

    return false;
}

int main() {
    ifstream inputFile("input1.txt");
    if (!inputFile) 
    {
        cerr << "Error opening file" << endl;
        return 1;
    }

    int n;
    inputFile >> n;
    vector<shared_ptr<Shape>> shapes;

    for (int i = 0; i < n; ++i) 
    {
        char type;
        inputFile >> type;
        if (type == 'R') 
        {
            int xmin, xmax, ymin, ymax;
            inputFile >> xmin >> xmax >> ymin >> ymax;
            shapes.push_back(make_shared<Rect>(xmin, xmax, ymin, ymax));
        }
        else if (type == 'C') 
        {
            int x, y, r;
            inputFile >> x >> y >> r;
            shapes.push_back(make_shared<Circle>(x, y, r));
        }
    }

    int cx, cy, cr;
    inputFile >> cx >> cy >> cr;
    Circle addedCircle(cx, cy, cr);

    vector<shared_ptr<Shape>> intersectingShapes;

    for (const auto& shape : shapes) 
    {
        if (shape->intersects(addedCircle)) 
        {
            intersectingShapes.push_back(shape);
        }
    }

    sort(intersectingShapes.begin(), intersectingShapes.end(), [](const shared_ptr<Shape>& a, const shared_ptr<Shape>& b) {
        return a->area() < b->area();
        });

    for (const auto& shape : intersectingShapes) 
    {
        shape->print();
    }

    return 0;
}

이 문제는 n개의 도형으로 입력이 주어집니다. 도형의 종류에는 직사각형과 원이 있습니다. 각 도형의 정보가 주어진 후, 추가로 하나의 원이 주어집니다. 이 원과 교차하는 도형들을 찾아서, 도형의 면적이 작은 순서대로 출력하는 프로그램을 작성합니다. 

 

먼저 Shape는 기본 도형 클래스로 순수 가상 함수로 면적을 계산하고 교차 확인 intersects 출력 print 메서드가 있습니다. 

 

Rect 사각형 클래스로 shape를 상속받습니다. 사각형의 최소/ 최대, x, y좌표를 멤버로 가집니다. area 메서드는 사각형의 면적을 계산하고 intersects 메서드는 다른 도형과의 교차 여부를 확인합니다. print 메서드는 사각형의 정보를 출력합니다. 

 

class Circle : public Shape 
{
private:
    int x, y, r;
public:
    Circle(int x, int y, int r) 
        : x(x), y(y), r(r) 
    {}

    double area() const override 
    {
        return 3.14 * r * r;
    }

    bool intersects(const Shape& other) const override;

    bool intersects(const Rect& rect) const 
    {
        int nearestX = max(rect.xmin, min(x, rect.xmax));
        int nearestY = max(rect.ymin, min(y, rect.ymax));
        int deltaX = x - nearestX;
        int deltaY = y - nearestY;
        return (deltaX * deltaX + deltaY * deltaY) <= (r * r);
    }

    bool intersects(const Circle& other) const 
    {
        int dx = x - other.x;
        int dy = y - other.y;
        double distance = sqrt(dx * dx + dy * dy);
        return distance <= (r + other.r);
    }

    void print() const override 
    {
        cout << "C " << x << " " << y << " " << r << endl;
    }
};

circle 클래스의 정의

Circle : 원 클래스, shape를 상속받습니다. 원의 중심 좌표 x, y와 반지름 r을 멤버로 가집니다. area 메서드는 원의 면적을 계산하고 intersects 메서드는 다른 도형과의 교차 여부를 확인합니다. print 메서드는 원의 정보를 출력합니다. 

 

bool Rect::intersects(const Shape& other) const 
{
    const Rect* r = dynamic_cast<const Rect*>(&other);
    if (r) return intersects(*r);

    const Circle* c = dynamic_cast<const Circle*>(&other);
    if (c) return intersects(*c);

    return false;
}

bool Rect::intersects(const Circle& other) const 
{
    return other.intersects(*this);
}

bool Circle::intersects(const Shape& other) const 
{
    const Circle* c = dynamic_cast<const Circle*>(&other);
    if (c) return intersects(*c);

    const Rect* r = dynamic_cast<const Rect*>(&other);
    if (r) return intersects(*r);

    return false;
}

intersects 메서드의 구현

Rect 와 Circle 클래스의 intersects 메서드는 주어진 도형과의 교차 여부를 확인합니다. dynamic_cast를 사용하여 다른 도형이 어떤 타입인지 확인한 후, 해당 타입에 맞는 교차 여부를 계산합니다. 

 

main 함수 구현

int main() {
    ifstream inputFile("input1.txt");
    if (!inputFile) 
    {
        cerr << "Error opening file" << endl;
        return 1;
    }

    int n;
    inputFile >> n;
    vector<shared_ptr<Shape>> shapes;

    for (int i = 0; i < n; ++i) 
    {
        char type;
        inputFile >> type;
        if (type == 'R') 
        {
            int xmin, xmax, ymin, ymax;
            inputFile >> xmin >> xmax >> ymin >> ymax;
            shapes.push_back(make_shared<Rect>(xmin, xmax, ymin, ymax));
        }
        else if (type == 'C') 
        {
            int x, y, r;
            inputFile >> x >> y >> r;
            shapes.push_back(make_shared<Circle>(x, y, r));
        }
    }

    int cx, cy, cr;
    inputFile >> cx >> cy >> cr;
    Circle addedCircle(cx, cy, cr);

    vector<shared_ptr<Shape>> intersectingShapes;

    for (const auto& shape : shapes) 
    {
        if (shape->intersects(addedCircle)) 
        {
            intersectingShapes.push_back(shape);
        }
    }

    sort(intersectingShapes.begin(), intersectingShapes.end(), [](const shared_ptr<Shape>& a, const shared_ptr<Shape>& b) {
        return a->area() < b->area();
        });

    for (const auto& shape : intersectingShapes) 
    {
        shape->print();
    }

    return 0;
}

main 함수에서는 파일에서 도형 정보를 읽고, 추가된 원과 교차하는 도형을 찾아서 면적 기준으로 정렬하여 출력합니다. 

 

ifstream inputFile("input1. txt") 입력 파일을 엽니다.

 

int n; inputFile >> n; 도형의 개수를 읽습니다.

 

vector<shared_ptr<Shape>> shapes; 는 도형들을 저장할 벡터를 만듭니다.

 

for(int i=0; i<n; ++i); 는 도형 정보를 읽어와서 shapes 벡터에 추가합니다. 

 

int cx, cy, cr; inputFile >> cx >> cy >> cr; 추가된 원의 정보를 읽습니다.

 

Circle addedCircle(cx, cy, cr); 은 추가된 원 객체를 생성합니다. 

 

vector<shared_ptr<shape>> intersectingShapes;는 교차하는 도형의 저장할 벡터를 만듭니다.

 

for(const auto & shape : shapes): shapes 는 벡터의 모든 도형에 대해 교차 여부를 판단하고, 교차하는 도형을 intersectingShapes 벡터에 추가합니다.

 

sort(intersectingShapes.begin(), intersectingShapes.end(), [](const shared_ptr .... 면적 기준으로 정렬합니다. 정렬된 도형들을 출력합니다.

 

2번 문제 응용

여러 개의 도형이 입력으로 주어집니다. 도형의 종류에는 직사각형(Rect)과 원(Circle)이 있습니다. 각 도형의 정보가 주어진 후, 추가로 하나의 직사각형 또는 원이 주어집니다. 이 도형과 교차하는 다른 도형들을 찾아서, 도형의 면적이 작은 순서대로 출력하는 프로그램을 작성하세요. 입력은 텍스트 파일 input2.txt로부터 읽어옵니다. 출력은 교차하는 도형들의 정보를 면적의 오름차순으로 정렬하여 화면에 출력합니다.

 

요구사항:
1.Shape 클래스는 순수 가상 함수로 area(), intersects(const Shape&), print() 메서드를 포함해야 합니다.
2.Rect 클래스와 Circle 클래스는 Shape 클래스를 상속받아야 합니다.
3.새로운 도형이 추가될 수 있도록 프로그램을 유연하게 설계해야 합니다.
4.도형이 서로 교차하는지 여부를 판단하는 로직을 구현해야 합니다.
5.면적 기준으로 정렬된 교차하는 도형의 목록을 출력해야 합니다.

 

#include <iostream>
#include <fstream>
#include <vector>
#include <cmath>
#include <algorithm>
#include <memory>

using namespace std;

class Circle;

class Shape {
public:
    virtual double area() const = 0;
    virtual bool intersects(const Shape& other) const = 0;
    virtual void print() const = 0;
    virtual ~Shape() = default;
};

class Rect : public Shape 
{
private:
    int xmin, xmax, ymin, ymax;
public:
    Rect(int xmin, int xmax, int ymin, int ymax) 
        : xmin(xmin), xmax(xmax), ymin(ymin), ymax(ymax) 
    {}

    double area() const override
    {
        return (xmax - xmin) * (ymax - ymin);
    }

    bool intersects(const Shape& other) const override;

    bool intersects(const Rect& other) const 
    {
        return !(xmax < other.xmin || xmin > other.xmax || ymax < other.ymin || ymin > other.ymax);
    }

    bool intersects(const Circle& other) const;

    void print() const override 
    {
        cout << "R " << xmin << " " << xmax << " " << ymin << " " << ymax << endl;
    }

    friend class Circle;
};

class Circle : public Shape 
{
private:
    int x, y, r;
public:
    Circle(int x, int y, int r) 
        : x(x), y(y), r(r) 
    {}

    double area() const override 
    {
        return 3.14 * r * r;
    }

    bool intersects(const Shape& other) const override;

    bool intersects(const Rect& rect) const 
    {
        int nearestX = max(rect.xmin, min(x, rect.xmax));
        int nearestY = max(rect.ymin, min(y, rect.ymax));
        int deltaX = x - nearestX;
        int deltaY = y - nearestY;
        return (deltaX * deltaX + deltaY * deltaY) <= (r * r);
    }

    bool intersects(const Circle& other) const 
    {
        int dx = x - other.x;
        int dy = y - other.y;
        double distance = sqrt(dx * dx + dy * dy);
        return distance <= (r + other.r);
    }

    void print() const override 
    {
        cout << "C " << x << " " << y << " " << r << endl;
    }
};

bool Rect::intersects(const Shape& other) const 
{
    const Rect* r = dynamic_cast<const Rect*>(&other);
    if (r) return intersects(*r);

    const Circle* c = dynamic_cast<const Circle*>(&other);
    if (c) return intersects(*c);

    return false;
}

bool Rect::intersects(const Circle& other) const 
{
    return other.intersects(*this);
}

bool Circle::intersects(const Shape& other) const 
{
    const Circle* c = dynamic_cast<const Circle*>(&other);
    if (c) return intersects(*c);

    const Rect* r = dynamic_cast<const Rect*>(&other);
    if (r) return intersects(*r);

    return false;
}

int main() {
    ifstream inputFile("input2.txt");
    if (!inputFile) 
    {
        cerr << "Error opening file" << endl;
        return 1;
    }

    int n;
    inputFile >> n;
    vector<shared_ptr<Shape>> shapes;

    for (int i = 0; i < n; ++i) 
    {
        char type;
        inputFile >> type;
        if (type == 'R') 
        {
            int xmin, xmax, ymin, ymax;
            inputFile >> xmin >> xmax >> ymin >> ymax;
            shapes.push_back(make_shared<Rect>(xmin, xmax, ymin, ymax));
        }
        else if (type == 'C') 
        {
            int x, y, r;
            inputFile >> x >> y >> r;
            shapes.push_back(make_shared<Circle>(x, y, r));
        }
    }

    char addedType;
    inputFile >> addedType;

    shared_ptr<Shape> addedShape;
    if (addedType == 'R') {
        int xmin, xmax, ymin, ymax;
        inputFile >> xmin >> xmax >> ymin >> ymax;
        addedShape = make_shared<Rect>(xmin, xmax, ymin, ymax);
    } else if (addedType == 'C') {
        int x, y, r;
        inputFile >> x >> y >> r;
        addedShape = make_shared<Circle>(x, y, r);
    }

    vector<shared_ptr<Shape>> intersectingShapes;

    for (const auto& shape : shapes) 
    {
        if (shape->intersects(*addedShape)) 
        {
            intersectingShapes.push_back(shape);
        }
    }

    sort(intersectingShapes.begin(), intersectingShapes.end(), [](const shared_ptr<Shape>& a, const shared_ptr<Shape>& b) {
        return a->area() < b->area();
    });

    for (const auto& shape : intersectingShapes) 
    {
        shape->print();
    }

    return 0;
}

 

 

 

여러 개의 도형이 입력으로 주어집니다. 도형의 종류에는 직사각형(Rect)과 원(Circle)이 있습니다. 각 도형의 정보가 주어진 후, 추가로 하나의 직사각형 또는 원이 주어집니다. 이 추가된 도형과 교차하지 않는 기존 도형 중 면적이 가장 큰 도형을 찾아서 출력하는 프로그램을 작성하세요. 입력은 텍스트 파일 input3.txt로부터 읽어옵니다. 출력은 교차하지 않는 도형들 중 면적이 가장 큰 도형의 정보를 화면에 출력합니다.

#include <iostream>
#include <fstream>
#include <vector>
#include <cmath>
#include <algorithm>
#include <memory>

using namespace std;

class Circle;

class Shape {
public:
    virtual double area() const = 0;
    virtual bool intersects(const Shape& other) const = 0;
    virtual void print() const = 0;
    virtual ~Shape() = default;
};

class Rect : public Shape 
{
private:
    int xmin, xmax, ymin, ymax;
public:
    Rect(int xmin, int xmax, int ymin, int ymax) 
        : xmin(xmin), xmax(xmax), ymin(ymin), ymax(ymax) 
    {}

    double area() const override

 

반응형