반응형

문제

간단한 그래픽 편집기를 콘솔 바탕으로 만들어보자. 그래픽 편집기의 기능은 "삽입", "삭제", "모두보기", "종료" 의 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;
}

 

반응형
반응형

문제

다음 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();
}
반응형
반응형

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() 함수와 실행 결과처럼 되도록  ForLoopAdder 클래스를 작성하라. ForLoopAdder 클래스의 calculate() 함수는 for 문을 이용하여 합을 구한다.

int main() {
	ForLoopAdder forLoop("For Loop");
	forLoop.run();
}

 

결과

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

 

소스코드

#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 ForLoopAdder : public LoopAdder {
	string name;
public:
	ForLoopAdder(string name = "") : LoopAdder(name) { this->name = name; }
	virtual int calculate() {
		int sum = 0;
		for (int i = getX(); i <= getY(); i++)
			sum += i;
		return sum;
	}
};

int main() {
	ForLoopAdder forLoop("For Loop");
	forLoop.run();
}
반응형

+ Recent posts