반응형

이전 문제까지는 명품JAVA 개정판이였고 이번 문제부터 개정 4판입니다.

 

문제

Vector<Shape>의 벡터를 이용하여 그래픽 편집기를 만들어보자. 본문 5.6절과 5.7절에서 사례로 든 추상 클래스 Shape과 Line, Rect, Circle 클래스 코드를 잘 완성하고 이를 활용하여 "삽입", "삭제", "모두 보기", "종료"의 4가지 그래픽 편집 기능을 프로그램으로 작성하라. 6장 실습문제 6번을 Vector<Shape>을 이용하여 재작성하는 연습이다. Vector를 이용하면 6장 실습문제 6번보다 훨씬 간단히 작성됨을 경험할 수 있다.

출력 예시

그래픽 에디터 beauty을 실행합니다.
삽입(1), 삭제(2), 모두보기(3), 종료(4) >> 1
Line(1), Rect(2), Circle(3) >> 2
삽입(1), 삭제(2), 모두보기(3), 종료(4)>>1
Line(1), Rect(2), Circle(3) >> 3
삽입(1), 삭제(2), 모두보기(3), 종료(4)>>3
Rect
Circle
삽입(1), 삭제(2), 모두보기(3), 종료(4)>>2
삭제할 도형의 위치 >> 3
삭제할 수 없습니다.
삽입(1), 삭제(2), 모두보기(3), 종료(4)>>4
beauty을 종료합니다.

소스 코드

import java.util.Scanner;
import java.util.Vector;

abstract class Shape{
	public Shape() {};
	public abstract String draw(); 
}
class LineTen extends Shape{
	@Override
	public String draw() {
		return "Line";
	}
}
class RectTen extends Shape{
	@Override
	public String draw() {
		return "Rect";
	}
}
class CircleTen extends Shape{
	@Override
	public String draw() {
		return "Circle";
	}
}

class GraphicEditorbeauty{
	Vector<Shape> v = new Vector<Shape>();
	
	public void Menu() {
		Scanner s = new Scanner(System.in);
		System.out.println("그래픽 에디터 beauty을 실행합니다.");
		while(true) {
		System.out.print("삽입(1), 삭제(2), 모두보기(3), 종료(4)>>");
		int input = s.nextInt();
		switch(input) {
		case 1:
			addshape(s);
			break;
		case 2:
			removeshape(s);
			break;
		case 3:
			Print();
			break;
		case 4:
			System.out.println("beauty을 종료합니다.");
			System.exit(0);
			break;
		default:
			break;
		}
		}
	}
	private void Print() {
		for(int i = 0;i<v.size();i++)
		{
			System.out.println(v.get(i).draw());
		}
	}
	private void addshape(Scanner s) {
		System.out.print("Line(1), Rect(2), Circle(3) >> ");
		int input = s.nextInt();
		switch(input) {
		case 1:
			LineTen L = new LineTen();
			v.add(L);
			break;
		case 2:
			RectTen R = new RectTen();
			v.add(R);
			break;
		case 3:
			CircleTen C = new CircleTen();
			v.add(C);
			break;
		default:
			System.out.println("잘못된 입력");
			break;
		}
	}
	private void removeshape(Scanner s) {
		System.out.println("삭제할 도형의 위치 >> ");
		int remove = s.nextInt();
		if(v.size() <= remove) {
			System.out.println("삭제할 수 없습니다.");
		}
		else
			v.remove(remove);
	}
	
}

public class Main10 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		GraphicEditorbeauty GE = new GraphicEditorbeauty();
		GE.Menu();
	}

}
반응형
반응형

문제

main() 함수를 다음과 같이 수행할 수 있도록 GrapgicObject를 상속받는 Rect와 Line을 작성하고, GraphicEditor 클래스에 필요한 메소드 add()와 draw()를 작성하여 완성하라

문제 소스 코드

abstract class GraphicObject{
	int x,y,w,h;
	GraphicObject(int x,int y,int w,int h){
		this.x = x;
		this.y = y;
		this.w = w;
		this.h = h;
	}
	public abstract void view();
}

public class GraphicEditor {
	Vector<GraphicObject> v= new Vector<GraphicObject>();
	
	void add(GraphicObject ob) {
		
	}
	void draw() {
		
	}
	
	public static void main(String[] args) {
		GraphicEditor g = new GraphicEditor();
		g.add(new Rect(2,2,3,4)); // (2,2)에서 3x4짜리 사각형
		g.add(new Line(3,3,8,8)); // (3,3)에서 8x8의 사각형 내의 대각선 직선
		g.add(new Line(2,5,6,6)); // (2,5)에서 6x6의 사각형 내의 대각선 직선
        	g.draw();
	}

}

결과 예시

2, 2 -> 3, 4의 사각형
3, 3 -> 8, 8의 선
2, 5 -> 6, 6의 선

소스코드

import java.util.Iterator;
import java.util.Vector;

abstract class GraphicObject{
	int x,y,w,h;
	GraphicObject(int x,int y,int w,int h){
		this.x = x;
		this.y = y;
		this.w = w;
		this.h = h;
	}
	public abstract void view();
}
class Rect extends GraphicObject{
	Rect(int x,int y,int w,int h){
		super(x,y,w,h);
	}
	
	public void view() {
		System.out.println(x + ", " + y +" -> " + w + ", " + h + "의 사각형");
	}
}

class Line extends GraphicObject{
	Line(int x,int y,int w,int h){
		super(x,y,w,h);
	}
	
	public void view() {
		System.out.println(x + ", " + y +" -> " + w + ", " + h + "의 선");
	}
}
public class GraphicEditor {
	Vector<GraphicObject> v= new Vector<GraphicObject>();
	
	void add(GraphicObject ob) {
		v.add(ob);
	}
	void draw() {
		Iterator<GraphicObject> it = v.iterator();
		while(it.hasNext()) {
			it.next().view();
		}
	}
	
	public static void main(String[] args) {
		GraphicEditor g = new GraphicEditor();
		g.add(new Rect(2,2,3,4)); // (2,2)에서 3x4짜리 사각형
		g.add(new Line(3,3,8,8)); // (3,3)에서 8x8의 사각형 내의 대각선 직선
		g.add(new Line(2,5,6,6)); // (2,5)에서 6x6의 사각형 내의 대각선 직선
		g.draw();
	}

}

결과

2, 2 -> 3, 4의 사각형
3, 3 -> 8, 8의 선
2, 5 -> 6, 6의 선
반응형
반응형

문제

간단한 그래픽 편집기를 콘솔 바탕으로 만들어보자. 그래픽 편집기의 기능은 "삽입", "삭제", "모두보기", "종료" 의 4가지이고, 실행 과정은 다음과 같다. (연결리스트 문제입니다.)

 

결과

 

소스코드

#include<iostream>
using namespace std;
class Shape {
	Shape* next;
protected:
	virtual void draw() = 0;
public:
	Shape() { next = NULL; }
	void paint() { draw(); }
	Shape* add(Shape* p) { this->next = p; return p; }
	Shape* getNext() { return next; }
	void setNext(Shape* p) { next = p; }
};
class Line : public Shape {
public:
	virtual void draw() { cout << "Line" << endl; }
};
class Circle : public Shape {
public:
	virtual void draw() { cout << "Circle" << endl; }
};
class Rect : public Shape {
public:
	virtual void draw() { cout << "Rect" << endl; }
};
class UI {
public:
	static int Mainmenu() {
		int input;
		cout << "삽입:1, 삭제:2, 모두보기:3, 종료:4 >> ";
		cin >> input;
		return input;
	}
	static int Insert() {
		int input;
		cout << "선:1, 원:2, 사각형:3 >> ";
		cin >> input;
		return input;
	}
	static int Delete() {
		int input;
		cout << "삭제하고자 하는 도형의 인덱스 >> ";
		cin >> input;
		return input;
	}
};
class GraphicEditor {
	Shape* pStart;
	Shape* pLast;
	int size;
public:
	GraphicEditor() { pStart = NULL; pLast = NULL; size = 0; }
	void make_shape() {
		cout << "그래픽 에디터입니다." << endl;
		while (true) {
			int input;
			input = UI::Mainmenu(); //처음 메뉴중 선택
			switch (input)
			{
			case 1: //1번 선택시
				input = UI::Insert(); // 도형 선택
				newshape(input);
				break;
			case 2:
				input = UI::Delete();
				delshape(input);
				break;
			case 3:
				show();
				break;
			case 4:
				exit(1);
			default:
				cout << "존재 하지 않는 메뉴" << endl;
				break;
			}
		}
	}
	void newshape(int input) {
		switch (input)
		{
		case 1:
			if (size == 0) { //처음 입력시
				pStart = new Line();
				pLast = pStart;
			}
			else  //아닐 시
				pLast = pLast->add(new Line());
			size++;
			break;
		case 2:
			if (size == 0) { //처음 입력시
				pStart = new Circle();
				pLast = pStart;
			}
			else  //아닐 시
				pLast = pLast->add(new Circle());
			size++;
			break;
		case 3:
			if (size == 0) { //처음 입력시
				pStart = new Rect();
				pLast = pStart;
			}
			else  //아닐 시
				pLast = pLast->add(new Rect());
			size++;
			break;
		default:
			cout << "존재 하지 않는 메뉴" << endl;
			break;
		}
	}
	void delshape(int n) {
		Shape* removenode = NULL;

		if (-1 > n || n > size - 1)
			cout << "존재 하지 않습니다." << endl;
		else {
			if (n == 0)
			{ //처음의 값을 삭제할 때는 pStart를 이용하여 삭제한다.
				removenode = pStart;
				pStart = pStart->getNext();
			}
			else { //아니라면
				int i = 1;
				for (Shape* p = pStart; p != NULL; p = p->getNext()) {
					//pStart 다음 값부터 그 다음값이 NULL이 아닐때까지 반복
					if (i == n) {
						removenode = p->getNext();
						//예) 1번째라면 이 반복문의 시작은 pStart이므로 다음 값을 삭제할 노드에 옮겨준뒤
						p->setNext(removenode->getNext());
						//p의 next가 가리키고 있는 노드를 현재의 p next로 옮겨주어 삭제할 노드를 한칸 띄어 이동하게 만든다.
					}
					i++;
				}
			}
			size--;
			delete removenode;
		}
	}
	void show()
	{
		if (size == 0)
			cout << "아무것도 존재하지 않습니다." << endl;
		else {
			int i = 0;
			for (Shape* p = pStart; p != NULL; p = p->getNext()) {
				cout << i << ": ";
				p->paint();
				i++;
			}
		}
	}
};

int main() {
	GraphicEditor* shape = new GraphicEditor;
	shape->make_shape();
	delete shape;
}

 

반응형
반응형

8장 8번을 응용한 문제입니다.

https://p-coding.tistory.com/24

 

명품 C++ Programming 실습문제 8장 8번

문제 다음 그림과 같은 상속 구조를 갖는 클래스를 설계한다. 모든 프린터는 모델명(model), 제조사(manufacturer), 인쇄 매수(printedCount), 인쇄 종이 잔량(availableCount)을 나타내는 정보와 print(int pages..

p-coding.tistory.com

문제

다음 그림과 같은 상속 구조를 갖는 클래스를 설계한다.

모든 프린터는 모델명(model), 제조사(manufacturer), 인쇄 매수(printedCount), 인쇄 종이 잔량(availableCount)을 나타내는 정보와 print(int pages) 멤버 함수를 가지며, print()가 호출할 때마다 pages 매의 용지를 사용한다. 잉크젯 프린터는 잉크 잔량(availableInk) 정보와 printInkJet(int pages) 멤버 함수를 추가적으로 가지며, 레이저 프린터는 토너 잔량(availableToner) 정보와 역시 printLaser(int pages) 멤버 함수를 추가적으로 가진다. 각 클래스에 적절한 접근 지정으로 멤버 변수와 함수, 생성자, 소멸자를 작성하고, 다음과 같이 실행되도록 전체 프로그램을 완성하라. 잉크젯 프린터 객체와 레이저 프린터 객체를 각각 하나만 동적 생성하여 시작한다.

결과

 

소스코드

#include<iostream>
using namespace std;
#include<iostream>
#include<string>
using namespace std;
class Printer {
	string model;		 //모델
	string manufacturer; //제조사
	int printedCount;	 //인쇄 매수
	int availableCount;  //인쇄 잔량
public:
	Printer(string m, string f, int ac) {
		model = m;
		manufacturer = f;
		availableCount = ac;
	}
	string getmodel() { return model; }				//모델명 리턴
	string getmanufacturer() { return manufacturer; }  //제조사 리턴
	int getCount() { return availableCount; } //인쇄 잔량 리턴
	virtual void show() = 0;
	virtual int getavailable() = 0;
	virtual void printitem(int pages) = 0;
	virtual int getavailableCount() = 0;
	void print(int pages) {
		printedCount = pages;
		availableCount -= printedCount;
	}

};
class IPrinter : public Printer {
	int availbleInk;	 //잉크 잔량
public:
	IPrinter(string m, string f, int aCount, int aInk) : Printer(m, f, aCount) { availbleInk = aInk; }
	virtual int getavailableCount() { return getCount(); }
	virtual void printitem(int pages) {
		availbleInk -= pages;
		print(pages);
	}
	virtual int getavailable() { return availbleInk; }
	virtual void show() {
		cout << getmodel() << ", " << getmanufacturer()
			<< ", 남은 종이" << getavailableCount() << ", 남은 잉크" << getavailable() << endl;
	}
};
class RPrinter : public Printer {
	int availableToner;	 //토너 잔량
public:
	RPrinter(string m, string f, int aCount, int aToner) : Printer(m, f, aCount) { availableToner = aToner; } //토너 초기화
	virtual int getavailableCount() { return getCount(); }
	virtual void printitem(int pages) {
		availableToner -= pages;
		print(pages);
	}
	virtual int getavailable() { return availableToner; }
	virtual void show() {
		cout << getmodel() << ", " << getmanufacturer()
			<< ", 남은 종이" << getavailableCount() << ", 남은 토너" << getavailable() << endl;
	}
};
int main()
{
	IPrinter IP("Officejet V40", "HP", 5, 10);
	RPrinter RP("SCX-6x45", "삼성전자", 3, 20);
	char q = 'y';
	int printer, pages;
	cout << "현재 작동중인 2대의 프린터는 아래와 같다" << endl;
	cout << "잉크젯 : ";
	IP.show();
	cout << "레이저 : ";
	RP.show();

	while (true) {
		cout << endl;
		cout << "프린터 (1:잉크젯, 2:레이저)와 매수 입력>>";
		cin >> printer >> pages;
		if (!(printer == 1 || printer == 2)) //프리터 1번 또는 2번을 선택하지 않았다면
			cout << "프린터가 존재하지 않습니다." << endl;
		else
		{
			if (printer == 1) { //잉크젯 선택
				if (IP.getavailableCount() < pages) //용지가 부족할 경우
					cout << "용지가 부족하여 프린트할 수 없습니다." << endl;
				else {
					IP.printitem(pages);
					cout << "프린터하였습니다.\n";
				}
			}
			else { //그 외 선택
				if (RP.getavailableCount() < pages) //용지가 부족할 경우
					cout << "용지가 부족하여 프린트할 수 없습니다." << endl;
				else {
					RP.printitem(pages);
					cout << "프린터하였습니다.\n";
				}
			}
		}
		IP.show();
		RP.show();
		cout << "계속 프린트 하시겠습니까?(y/n)>>";
		cin >> q; //n이면 루프 종료
		if (q == 'y')
			continue;
		else //그이외에의 값 종료 while(q != 'n')을 쓰셔도 됩니다.
			exit(1);
	}
}
반응형
반응형

7~8번에 쓰이는 사각형에 내접하는 도형을 표현하기 위한 Shape 클래스 입니다.

class Shape {
protected:
	string name; // 도형의 이름
	int width, height; // 도형이 내접하는 사각형의 너비와 높이
public:
	Shape(string n = "", int w = 0, int h = 0) { name = n; width = w; height = h; }
	virtual double getArea() { return 0; } //dummy 값 리턴
	string getName() { return name; } //이름 리턴
};

 

문제 7

Shape 클래스를 상속받아 타원을 표현하는 Oval, 사각형을 표현하는 Rect, 삼각형을 표현하는 Triangular 클래스를 작성하라. main() 을 작성하고 실행하면 다음과 같다.

int main() {
	Shape* p[3];
	p[0] = new Oval("빈대떡", 10, 20);
	p[1] = new Rect("찰떡", 30, 40);
	p[2] = new Triangular("토스트", 30, 40);
	for (int i = 0; i < 3; i++)
		cout << p[i]->getName() << " 넓이는 " << p[i]->getArea() << endl;

	for (int i = 0; i < 3; i++)delete p[i];
}

 

결과

빈대떡 넓이는 628
찰떡 넓이는 1200
토스트 넓이는 600

 

소스코드

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

class Shape {
protected:
	string name; // 도형의 이름
	int width, height; // 도형이 내접하는 사각형의 너비와 높이
public:
	Shape(string n = "", int w = 0, int h = 0) { name = n; width = w; height = h; }
	virtual double getArea() { return 0; } //dummy 값 리턴
	string getName() { return name; } //이름 리턴
};
class Oval : public Shape {
public:
	Oval(string name, int width, int height) : Shape(name, width, height) {};
	virtual double getArea()
	{
		return width * height * 3.14;
	}
};
class Rect : public Shape {
public:
	Rect(string name, int width, int height) : Shape(name, width, height) {};
	virtual double getArea()
	{
		return width * height;
	}
};
class Triangular : public Shape {
public:
	Triangular(string name, int width, int height) : Shape(name, width, height) {};
	virtual double getArea()
	{
		return (width * height) / 2;
	}
};
int main() {
	Shape* p[3];
	p[0] = new Oval("빈대떡", 10, 20);
	p[1] = new Rect("찰떡", 30, 40);
	p[2] = new Triangular("토스트", 30, 40);
	for (int i = 0; i < 3; i++)
		cout << p[i]->getName() << " 넓이는 " << p[i]->getArea() << endl;

	for (int i = 0; i < 3; i++)delete p[i];
}

 

문제 8

문제 7에 주어진 Shape 클래스를 추상 클래스로 만들고 문제 7을 다시 작성하라.

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

class Shape {
protected:
	string name; // 도형의 이름
	int width, height; // 도형이 내접하는 사각형의 너비와 높이
public:
	Shape(string n = "", int w = 0, int h = 0) { name = n; width = w; height = h; }
	virtual double getArea() { return 0; } //dummy 값 리턴
	string getName() { return name; } //이름 리턴
};
class Oval : public Shape {
public:
	Oval(string name, int width, int height) : Shape(name, width, height) {};
	 double getArea()
	{
		return width * height * 3.14;
	}
};
class Rect : public Shape {
public:
	Rect(string name, int width, int height) : Shape(name, width, height) {};
	 double getArea()
	{
		return width * height;
	}
};
class Triangular : public Shape {
public:
	Triangular(string name, int width, int height) : Shape(name, width, height) {};
	 double getArea()
	{
		return (width * height) / 2;
	}
};
int main() {
	Shape* p[3];
	p[0] = new Oval("빈대떡", 10, 20);
	p[1] = new Rect("찰떡", 30, 40);
	p[2] = new Triangular("토스트", 30, 40);
	for (int i = 0; i < 3; i++)
		cout << p[i]->getName() << " 넓이는 " << p[i]->getArea() << endl;

	for (int i = 0; i < 3; i++)delete p[i];
}
반응형
반응형

문제

다음 AbstractStack은 정수 스택 클래스로서 추상 클래스이다.

class AbstractStack {
public:
	virtual bool push(int n) = 0; //스택에 n을 푸시한다. 스택이 full이면 false 리턴
	virtual bool pop(int& n) = 0; //스택에서 팝한 정수를 n에 저장하고 스택이 empty이면 리턴
	virtual int size() = 0; // 현재 스택에 저장된 개수 리턴
};

이를 상속받아 정수를 푸시, 팝하는 IntStack 클래스를 만들고 사용 사례를 보아라.

 

소스코드

#include<iostream>
using namespace std;

class AbstractStack {
public:
	virtual bool push(int n) = 0; //스택에 n을 푸시한다. 스택이 full이면 false 리턴
	virtual bool pop(int& n) = 0; //스택에서 팝한 정수를 n에 저장하고 스택이 empty이면 리턴

	virtual int size() = 0; // 현재 스택에 저장된 개수 리턴
};

class IntStack : public AbstractStack {
	int* data;
	int s, top;
public:
	IntStack(int s) {
		this->s = s;
		data = new int[s];
		top = -1;
	}
	~IntStack() { delete[] data; }
	void show() {
		for (int i = top; i >= 0; i--)
		{
			cout << data[i] << " ";
		}
		cout << endl;
	}
	virtual bool push(int n) {
		if (top + 1 >= s)return false; //top size보다 같거나 크면 false리턴
		data[++top] = n; //아니라면 값을 넣은 후 true 리턴
		return true;
	}
	virtual bool pop(int& n) {
		if (top <= -1)return false; //top이 -1보다 같거나 작다면 false리턴
		n = data[top--];
		return true;
	}
	virtual int size() {
		return top + 1; //저장된 개수 리턴 0부터 시작하므로 +1
	}
};

int main()
{
	int size, menu, push, pop;

	cout << "스택의 크기는?>> ";
	cin >> size;

	IntStack stack(size);

	while (true) {
		cout << endl << "1. 푸시 2. 팝 3. 스택보기 4. 종료" << endl << "메뉴 선택>> ";
		cin >> menu;
		switch (menu) {
		case 1:
			cout << "push 할 값>> ";
			cin >> push;
			if (stack.push(push))
				cout << "push 완료" << endl;
			else
				cout << "push할 공간이 없습니다." << endl;
			break;
		case 2:
			if (stack.pop(pop))
				cout << "pop 완료 pop한 값 : " << pop << endl;
			else
				cout << "빈 스택입니다." << endl;
			break;
		case 3:
			cout << "스택 데이터 : ";
			stack.show();
			break;
		case 4:
			cout << "종료" << endl;
			exit(1);
		default:
			cout << "잘못 입력" << endl;
			break;
		}
	}
}

 

결과

 

반응형
반응형

3~4번에 쓰이는 추상 클래스 LoopAdder 입니다.

class LoopAdder { // 추상 클래스 
	string name; // 루프의 이름 
	int x, y, sum; // x에서 y까지의 합은 sum 
	void read(); // x, y 값을 읽어 들이는 함수 
	void write(); // sum을 출력하는 함수 
protected:
	LoopAdder(string name = "") { // 루프의 이름을 받는다. 초깃값은 "" 
		this->name = name;
	}
	int getX() { return x; }
	int getY() { return y; }
	virtual int calculate() = 0; // 순수 가상 함수. 루프를 돌며 합을 구하는 함수 
public:
	void run(); // 연산을 진행하는 함수 
};

void LoopAdder::read() { // x, y 입력 
	cout << name << ":" << endl;
	cout << "처음 수에서 두번째 수까지 더한다. 두 수를 입력하세요 >> ";
	cin >> x >> y;
}

void LoopAdder::write() { // 결과 sum 출력 
	cout << x << "에서 " << y << "까지의 합 = " << sum << " 입니다" << endl;
}

void LoopAdder::run() {
	read(); // x, y를 읽는다 
	sum = calculate(); // 루프를 돌면서 계산한다. 
	write(); // 결과 sum을 출력한다. 
}

 

문제

LoopAdder 클래스를 상속받아 다음 main() 함수와 실행 결과처럼 되도록 WhileLoopAdder, DowhileLoopAdder 클래스를 작성하라. while 문, do-while 문을 이용하여 합을 구하도록 calculate() 함수를 각각 작성하면 된다.

int main() {
	WhileLoopAdder whileLoop("While Loop");
	DoWhileLoopAdder doWhileLoop("Do While Loop");

	whileLoop.run();
	doWhileLoop.run();
}

 

결과

While Loop :
처음 수에서 두번째 수까지 더합니다.두 수를 입력하세요 >> 3 10
3에서 5까지의 합 = 12 입니다 Do While Loop :
처음 수에서 두번째 수까지 더합니다.두 수를 입력하세요 >> 10 20
10에서 20까지의 합 = 165

 

소스코드

#include<iostream>
using namespace std;
class LoopAdder { // 추상 클래스 
	string name; // 루프의 이름 
	int x, y, sum; // x에서 y까지의 합은 sum 
	void read(); // x, y 값을 읽어드리는 함수 
	void write(); // sum을 출력하는 함수 
protected:
	LoopAdder(string name = "") { // 루프의 이름을 받는다. 초깃값은 "" 
		this->name = name;
	}
	int getX() { return x; }
	int getY() { return y; }
	virtual int calculate() = 0; // 순수 가상 함수. 루프를 돌며 합을 구하는 함수 
public:
	void run(); // 연산을 진행하는 함수 
};

void LoopAdder::read() { // x, y 입력 
	cout << name << ":" << endl;
	cout << "처음 수에서 두번째 수까지 더한다. 두 수를 입력하세요 >> ";
	cin >> x >> y;
}

void LoopAdder::write() { // 결과 sum 출력 
	cout << x << "에서 " << y << "까지의 합 = " << sum << " 입니다" << endl;
}

void LoopAdder::run() {
	read(); // x, y를 읽는다 
	sum = calculate(); // 루프를 돌면서 계산한다. 
	write(); // 결과 sum을 출력한다. 
}
class WhileLoopAdder : public LoopAdder {
	string name;
public:
	WhileLoopAdder(string name = "") :LoopAdder(name) { this->name = name; }
	virtual int calculate() {
		int sum = 0;
		int x = getX();
		int y = getY();
		while (x <= y) {
			sum += x;
			x++;
		}
		return sum;
	}
};

class DoWhileLoopAdder : public LoopAdder {
	string name;
public:
	DoWhileLoopAdder(string name = "") :LoopAdder(name) { this->name = name; }
	virtual int calculate() {
		int sum = 0;
		int x = getX();
		int y = getY();
		do {
			sum += x;
			x++;
		} while (x <= y);
		return sum;
	}
};
int main() {
	WhileLoopAdder whileLoop("While Loop");
	DoWhileLoopAdder doWhileLoop("Do While Loop");

	whileLoop.run();
	doWhileLoop.run();
}
반응형
반응형

1~2번에 쓰이는 단위변환 추상 클래스 Converter입니다.

#include<iostream>
using namespace std;
class Converter {
protected:
	double ratio;
	virtual double convert(double src) = 0; //src를 다른 단위로 변환한다.
	virtual string getSourceString() = 0; //src 단위 명칭
	virtual string getDestString() = 0; //dest 단위 명칭
public:
	Converter(double ratio) { this->ratio = ratio; }
	void run() {
		double src;
		cout << getSourceString() << "을 " << getDestString() << "로 바꿉니다. ";
		cout << getSourceString() << "을 입력하세요>> ";
		cin >> src;
		cout << "변환 결과 : " << convert(src) << getDestString() << endl;
	}
};

 

문제

Converter 클래스를 상속받아 달러를 원화로 환산하는 WonToDollar 클래스를 작성하라. main() 함수와 실행 결과는 다음과 같다.

int main()
{
	WonToDallar wd(1010); //1달러에 10101원
	wd.run();
}

 

결과

원을 달러로 바꿉니다. 원을 입력하세요>> 10000
변환 결과 : 9.90099달러

 

소스코드

#include<iostream>
using namespace std;
class Converter {
protected:
	double ratio;
	virtual double convert(double src) = 0; //src를 다른 단위로 변환한다.
	virtual string getSourceString() = 0; //src 단위 명칭
	virtual string getDestString() = 0; //dest 단위 명칭
public:
	Converter(double ratio) { this->ratio = ratio; }
	void run() {
		double src;
		cout << getSourceString() << "을 " << getDestString() << "로 바꿉니다. ";
		cout << getSourceString() << "을 입력하세요>> ";
		cin >> src;
		cout << "변환 결과 : " << convert(src) << getDestString() << endl;
	}
};
class WonToDallar : public Converter
{
	int krw;
public:
	WonToDallar(int krw) : Converter(krw) { this->krw = krw; }
	virtual double convert(double src) {
		return src / krw;
	}
	virtual string getSourceString() {
		return "원";
	}
	virtual string getDestString() {
		return "달러";
	}
};
int main()
{
	WonToDallar wd(1010); //1달러에 10101원
	wd.run();
}

 

반응형
반응형

문제

다음 그림과 같은 상속 구조를 갖는 클래스를 설계한다.

모든 프린터는 모델명(model), 제조사(manufacturer), 인쇄 매수(printedCount), 인쇄 종이 잔량(availableCount)을 나타내는 정보와 print(int pages) 멤버 함수를 가지며, print()가 호출할 때마다 pages 매의 용지를 사용한다. 잉크젯 프린터는 잉크 잔량(availableInk) 정보와 printInkJet(int pages) 멤버 함수를 추가적으로 가지며, 레이저 프린터는 토너 잔량(availableToner) 정보와 역시 printLaser(int pages) 멤버 함수를 추가적으로 가진다. 각 클래스에 적절한 접근 지정으로 멤버 변수와 함수, 생성자, 소멸자를 작성하고, 다음과 같이 실행되도록 전체 프로그램을 완성하라. 잉크젯 프린터 객체와 레이저 프린터 객체를 각각 하나만 동적 생성하여 시작한다.

 

결과

 

소스코드

#include<iostream>
#include<string>
using namespace std;
class Printer {
	string model;		 //모델
	string manufacturer; //제조사
	int printedCount;	 //인쇄 매수
	int availableCount;  //인쇄 잔량
public:
	Printer(string m, string f, int ac) {
		model = m;
		manufacturer = f;
		availableCount = ac;
	}
	string getmodel() { return model; }				//모델명 리턴
	string getmanufacturer() { return manufacturer; }  //제조사 리턴
	int getavailableCount() { return availableCount; } //인쇄 잔량 리턴

	void print(int pages) {
		printedCount = pages;
		availableCount -= printedCount;
	}

};
class IPrinter : public Printer {
	int availbleInk;	 //잉크 잔량
public:
	IPrinter(string m, string f, int aCount, int aInk) : Printer(m, f, aCount) { availbleInk = aInk; }
	int getIavailableCount() { return getavailableCount(); }
	void printInkJet(int pages) {
		availbleInk -= pages;
		print(pages);
	}
	int getavailbleInk() { return availbleInk; }
	void show() {
		cout << getmodel() << ", " << getmanufacturer()
			<< ", 남은 종이" << getavailableCount() << ", 남은 잉크" << getavailbleInk() << endl;
	}
};
class RPrinter : public Printer {
	int availableToner;	 //토너 잔량
public:
	RPrinter(string m, string f, int aCount, int aToner) : Printer(m, f, aCount) { availableToner = aToner; } //토너 초기화
	int getRavailableCount() { return getavailableCount(); }
	void printLaser(int pages) {
		availableToner -= pages;
		print(pages);
	}
	int getavailableToner() { return availableToner; }
	void show() {
		cout << getmodel() << ", " << getmanufacturer()
			<< ", 남은 종이" << getavailableCount() << ", 남은 토너" << getavailableToner() << endl;
	}
};
int main()
{
	IPrinter IP("Officejet V40", "HP", 5, 10);
	RPrinter RP("SCX-6x45", "삼성전자", 3, 20);
	char q = 'y';
	int printer, pages;
	cout << "현재 작동중인 2대의 프린터는 아래와 같다" << endl;
	cout << "잉크젯 : ";
	IP.show();
	cout << "레이저 : ";
	RP.show();

	while (true) {
		cout << endl;
		cout << "프린터 (1:잉크젯, 2:레이저)와 매수 입력>>";
		cin >> printer >> pages;
		if (!(printer == 1 || printer == 2)) //프리터 1번 또는 2번을 선택하지 않았다면
			cout << "프린터가 존재하지 않습니다." << endl;
		else
		{
			if (printer == 1) { //잉크젯 선택
				if (IP.getIavailableCount() < pages) //용지가 부족할 경우
					cout << "용지가 부족하여 프린트할 수 없습니다." << endl;
				else {
					IP.printInkJet(pages);
					cout << "프린터하였습니다.\n";
				}
			}
			else { //그 외 선택
				if (RP.getRavailableCount() < pages) //용지가 부족할 경우
					cout << "용지가 부족하여 프린트할 수 없습니다." << endl;
				else {
					RP.printLaser(pages);
					cout << "프린터하였습니다.\n";
				}
			}
		}
		IP.show();
		RP.show();
		cout << "계속 프린트 하시겠습니까?(y/n)>>";
		cin >> q; //n이면 루프 종료
		if (q == 'y')
			continue;
		else //그이외에의 값 종료 while(q != 'n')을 쓰셔도 됩니다.
			exit(1); 
	}
}
반응형
반응형

문제

아래와 같은 BaseMemory 클래스를 상속받는 ROM(Read Only Memory), RAM 클래스를 작성하라. BaseMemory에 필요한 코드를 수정 추가하여 적절히 완성하라.

class BaseMemory {
	char* men;
protected:
	BaseMemory(int size) {
		men = new char[size];
	}
};

 

ROM은 읽기 전용 메모리이므로 작동 중에 값을 쓸 수가 없기 때문에, 공장에서 생산할 때 생산자가 요청한 데이터로 초기화하는데 이 작업을 굽는다(burn)라고 한다. 그러므로 ROM은 반드시 생성자에서 burn 작업이 일어나야 한다.

다음은 ROM과 RAM 메모리ㅣ를 생성하고 사용하는 사례이다. ROM의 0번지에서 4번지까지 읽어 RAM 메모리의 0~4번지에 쓰고, 다시 RAM 메모리의 값을 화면에 출력한다. 전체 프로그램을 완성하라.

int main()
{
	char x[5] = { 'h','e','l','l','o' };
	ROM biosROM(1024 * 10, x, 5); //10KB의 ROM메모리, 배열 x로 초기화됨
	RAM mainMemory(1024 * 1024); //1MB의 RAM메모리

	//0번지에서 4번지까지의 biosROM에서 읽어 mainMemory에 복사
	for (int i = 0; i < 5; i++)
		mainMemory.write(i, biosROM.read(i));
	for (int i = 0; i < 5; i++)
		cout << mainMemory.read(i);
}

 

결과

hello

 

소스코드

#include<iostream>
using namespace std;

class BaseMemory {
	char* men;
protected:
	BaseMemory(int size) {
		men = new char[size];
	}
	~BaseMemory() { delete [] men; }
	void setmen(int i, int data) { men[i] = data; }
	char getmen(int i) { return men[i]; }
};
class ROM : public BaseMemory {
public:
	ROM(int Memory, char x[], int size) : BaseMemory(Memory) {
		for (int i = 0; i < size; i++)
		{
			setmen(i, x[i]);
		}
	};
	char read(int i) { return getmen(i); }
};
class RAM : public BaseMemory {
public:
	RAM(int Memory) : BaseMemory(Memory) {};
	char read(int i) { return getmen(i); }
	void write(int i, char data) { setmen(i, data); }
};
int main()
{
	char x[5] = { 'h','e','l','l','o' };
	ROM biosROM(1024 * 10, x, 5); //10KB의 ROM메모리, 배열 x로 초기화됨
	RAM mainMemory(1024 * 1024); //1MB의 RAM메모리

	//0번지에서 4번지까지의 biosROM에서 읽어 mainMemory에 복사
	for (int i = 0; i < 5; i++)
		mainMemory.write(i, biosROM.read(i));
	for (int i = 0; i < 5; i++)
		cout << mainMemory.read(i);
}
반응형

+ Recent posts