1. 문제

 

7. 클래스 Accumulator는 add() 함수를 통해 계속 값을 누적하는 클래스로서, 다음과 같이 선언된다. Accumulator 클래스를  구현하라.

 

 

2. 결과

 

 

 

3. 코드

 

#include <iostream>
using namespace std;

class Accumulator {
	int value;
public : 
	Accumulator(int value){ this->value = value; }
	Accumulator& add(int n){ value += n; return *this; }
	int get(){ return value; }
};

int main() {
	Accumulator acc(10);
	acc.add(5).add(6).add(7);
	cout << acc.get() << endl;
}

 

 

4. 설명

 

Accumulator(int value)생성자에서 총 값 value를 입력된 매개변수로 초기화합니다.

 

Accumulator& add(int n) 로 입력된 n을 value의 더한 후 return *this;를 하여 줍니다.

 

이로써 main()에서 acc.add(5).add(6).add(7) 이렇게 연속적으로 add함수를 실행 할 수 있습니다.

 

 

 

1. 문제

 

6. 문제 5번의 MyIntStack를 수정하여 다음과 같이 선언하였다. 스택에 저장할 수 있는 정수의 최대 개수는 생성자에서 주어지고 size 멤버에 유지한다. MyIntStack 클래스를 작성하라.

 

MyIntStack 클래스를 활용하는 코드와 실행 결과는 다음과 같다.

 

 

2. 결과

 

 

 

3. 코드

 

#include <iostream>
using namespace std;

class MyIntStack {
	int *p;
	int size;
	int tos;
public : 
	MyIntStack();
	MyIntStack(int size){ tos=-1; p = new int[size]; this->size = size; }
	MyIntStack(MyIntStack& s);
	~MyIntStack(){ delete [] p; }
	bool push(int n);
	bool pop(int &n);
};

bool MyIntStack::push(int n) {
	tos++;
	if( tos == 10 ) 
		return false;
	else {
		p[tos] = n;
		return true;
	}
}
bool MyIntStack::pop(int &n) {
	if( tos == -1 )
		return false;
	else {
		n = p[tos];
		return true;
	}
	tos--;
}
MyIntStack::MyIntStack(MyIntStack& s){ 
	this->p = new int[s.size];
	this->size = s.size;
	this->tos = s.tos;
	for(int i=0; i<=s.tos; i++)
		this->p[i] = s.p[i];
}

int main() {
	MyIntStack a(10);
	a.push(10);
	a.push(20);
	MyIntStack b = a;
	b.push(30);

	int n;
	a.pop(n);
	cout << "스택 a에서 팝한 값 " << n << endl;
	b.pop(n);
	cout << "스택 b에서 팝한 값 " << n << endl;
}

 

 

4. 설명

 

5번과 다른점은 생성자의서 int형 변수를 하나 입력받아서 그만큼 배열을 동적 생성하고 또한 클래스 변수간의 "="를 사용

 

하기 위한 MyIntStack( MyIntStack& s); 생성자와 소멸자가 추가되었습니다.

 

MyIntStack( MyIntStack& s);의서는 깊은 복사를 하여서 정확하게 복사가 되도록 구현하였습니다.

 

 

소멸자에서는 동적으로 생성하였던 배열 p를 해제하여 줍니다.

 

 

 

1. 문제

 

5. 다음과 같이 선언된 정수를 저장하는 스택 클래스 MyIntStack을 구현하라.

 

MyIntStack 스택에 저장할 수 있는 정수의 최대 개수는 10이다.

 

MyIntStack 클래스를 활용하는 코드와 실행 결과는 다음과 같다.

 

 

2. 결과

 

 

 

3. 코드

 

#include <iostream>
using namespace std;

class MyIntStack {
	int p[10];
	int tos;
public : 
	MyIntStack(){ tos = 0; }
	bool push(int n);
	bool pop(int &n);
};
bool MyIntStack::push(int n) {
	if( tos == 10 ) 
		return false;
	else {
		p[tos] = n;
		tos++;
		return true;
	}
}
bool MyIntStack::pop(int &n) {
	tos--;
	if( tos == -1 )
		return false;
	else {
		n = p[tos];
		return true;
	}
}

int main() {
	MyIntStack a;
	for(int i=0; i<11; i++) {
		if(a.push(i) ) cout << i << ' ';
		else cout << endl << i+1 << " 번째 stack full" << endl;
	}
	int n;
	for(int i=0; i<11; i++) {
		if(a.pop(n)) cout << n << ' ';
		else cout << endl << i+1 << " 번째 stack empty";
	}
	cout << endl;
}

 

 

4. 설명

 

Stack은 선입선출의 구조로 가장 나중에 들어온 데이터가 가장 먼저 나갑니다.

 

Stack을 예로 들어 설명하면 책을 쌓는 것과 유사하다고 할 수 있습니다. 

 

책(데이터)이 쌓여서 만들어진 책 더미의서 책(데이터)을 추가할려면 가장 위(top)에다가 책을 추가합니다.

 

여기서 가장 위 top(높이)를 저장하고 있는 값이 멤버 변수 tos 입니다.

 

 

※ 배열의 인덱스는 0부터 시작하므로 클래스 MyIntStack의 생성자에서 tos = -1로 초기화 해줍니다.

 

 

 

1. 문제

 

4. find() 함수의 원형은 다음과 같다. 문자열 a에서 문자 c를 찾아, 문자 c가 있는 공간에 대한 참조를 리턴한다. 만일 문자 c를 찾을 수 없다면 success 참조 매개 변수에 false를 설정한다. 물론 찾게 되면 success에 true를 설정한다.

 

 

2. 결과

 

 

 

 

3. 코드

 

#include <iostream>
using namespace std;

char& find(char a[], char c, bool& success);

char& find(char a[], char c, bool& success) {

	for(int i=0; i< sizeof(a); i++)
		if( a[i] == c ) { 
			success = true;
			return a[i]; 
		}
		return *a;
}

int main() {
	char s[] = "Mike";
	bool b = false;
	char& loc = find(s, 'M', b);
	if( b == false) {
		cout << "M을 발견할 수 없다" << endl;
		return 0;
	}
	loc = 'm';
	cout << s << endl;
}

 

 

4. 설명

 

함수 find(s, 'M', b)는 문자열 s에서 'M'을 찾아서 존재한다면 false로 초기화 되어있는 success를 success = true;로 초기화 합니다.

 

또한, 참조에 의한 호출로서 문자 하나를 return 합니다.

 

return한 문자는 char& loc에 저장을 하였고 참조에 의한 호출이기 때문에 loc값을 바꾸면 함수 find()에서 return했던 값도 loc값에 따라 바꾸어집니다.

 

 

 

1. 문제

 

3. 다음 Circle 클래스가 있다.

 

Circle 객체 b를 a에 더하여 a를 키우고자 다음 함수를 작성하였다.

 

다음 코드를 실행하면 increaseBy() 함수는 목적대로 실행되는가?

 

main() 함수의 목적을 달성하도록 increaseBy() 함수를 수정하라.

 

 

2. 결과

 

 

 

3. 코드

 

#include <iostream>
using namespace std;

class Circle;
void increaseBy(Circle &a, Circle b);

class Circle {
	int radius;
public :
	Circle(int r) { radius = r; }
	int getRadius() { return radius;}
	void setRadius(int r) { radius = r; }
	void show() { cout << "반지름이 " << radius << "인 원" << endl; }
};

void increaseBy(Circle &a, Circle b) {
	int r = a.getRadius() + b.getRadius();
	a.setRadius(r);
}

int main() {
	
	Circle x(10), y(5);
	increaseBy(x, y);
	x.show();
}

 

 

4. 설명

 

문제 해결 전 주어진 void increaseBy(Circle a, Circle b)를 보면 어느 값도 return 하지 않는 void형 입니다.

 

그런데 매개변수들도 보면 둘 다 값에 의한 호출로서, 이 함수 increaseBy()에서 어떤 명령을 실행시켜도 increaseBy() 함수 공간에서만 실행되고 이 함수가 끝나면 increaseBy() 공간이 사라지게 됩니다.

 

 

그러므로 변한 값이 유지되도록 값이 변경될 Circle a를 값에 의한 호출이 아닌 참조에 의한 호출로서 바꾸어 주어서 increaseBy()함수 내에서 Circle a의 변한 값이 유지되도록 만들어 줍니다.

 

 

 

1. 문제

 

2. 아래와 같이 원형이 주어진 bigger()를 작성하고 사용자로부터 2개의 정수를 입력받아 큰 값을 출력하는 main()을 작성하라. bigger()는 인자로 주어진 a, b가 같으면 true, 아니면 flase를 리턴하고 큰 수는 big에 전달한다.

 

 

2. 결과

 

 

 

3. 코드

 

#include <iostream>
using namespace std;

bool bigger(int a, int b, int& big);

bool bigger(int a, int b, int& big) {
	if( a == b )
		return true;
	else {
		if( a>=b) big = a;
		else big = b;
		return false;
	}
}

int main() {
	int n=5, nn=9, big;

	if( bigger(n, nn, big) )
		cout << "두 수는 같습니다." << endl;
	else
		cout << "더 큰 수는 " << big << "입니다" << endl;

}

 

 

4. 설명

 

bool bigger() 함수는 두 수가 같은 경우 return true;를 두 값이 다른 경우 더 큰 값을 big에 저장한 후 return false;를 해줍니다.

 

return형이 bool이기 때문에 return은 true, false 값으로 해주셔야 합니다.

 

또한, 문제에서는 사용자로부터 2개의 정수를 입력받은 후 큰 값을 출력해야 되지만 저는 그냥 변수 2개를 초기화 한 후 비교하였습니다.

 

 

 

1. 문제

 

1. 두 개의 Circle 객체를 교환하는 swap() 함수를 '참조에 의한 호출'이 되도록 작성하고 호출하는 프로그램을 작성하라.

 

 

2. 결과

 

 

 

3. 코드

 

#include <iostream>
using namespace std;

class Circle;
void swap( Circle &c, Circle &cc );

class Circle {
	int r;
public :
	Circle(int r=1) { this->r = r; }
	void setRadius(int r) { this->r = r; }
	int getRadius() { return r;}
};

void swap( Circle &c, Circle &cc ) {
	int n;

	n=c.getRadius();
	c.setRadius(cc.getRadius() );
	cc.setRadius(n);
}

int main() {
	Circle a;
	Circle b(10);

	cout << "a 반지름 : " << a.getRadius() << endl;
	cout << "b 반지름 : " << b.getRadius() << endl;
	cout << "swap 후" << endl;
	swap(a, b);
	cout << "a 반지름 : " << a.getRadius() << endl;
	cout << "b 반지름 : " << b.getRadius() << endl;

}

 

 

4. 설명

 

Circle 클래스는 반지름을 저장하는 멤버 변수 r, 생성자, 반지름을 재설정하는 setRadius() 멤버 함수, 반지름을 return 해주는 멤버 함수 getRadius()로 구성 됩니다.

 

swap()함수는 Circle 변수 2개를 매개변수로 입력 받으면 두 Circle 객체의 반지름을 바꾸어 줍니다.

 

swap() 함수가 참조에 의한 호출이므로 swap함수에서 따로 값을 return 할 필요는 없습니다.

 

 

1. 문제

 

n명이 하는 한글 끝말잇기 게임을 작성해보자. 아래의 결과와 같이 선수의 수를 입력받고, 선수 각 사람의 이름을 입력받아 게임을 시작한다.

 

 

 

2. 결과

 

 

 

3. 코드

 

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

class Player {
	int number;
	int temp;
	string *name;
public :
	Player(int n) ;
	~Player() { delete [] name; }
	string getName();
};
Player::Player(int n) { 
	number = n; temp = -1;
	name = new string[number]; 
	fflush(stdin);
	for(int i=0; i<number; i++ ) {
		cout << "참가자의 이름을 입력하세요. 빈칸 없이>>";
		getline( cin, name[i] );
	}
}
string Player::getName() {
	temp++;
	if( temp >= number ) temp = 0;
	string named = name[temp];
	return named;
}

class WordGame {
	int num;
	string before, after;
public :
	WordGame();
	void game();
};
WordGame::WordGame() {
	before = "아버지";
}
void WordGame::game() {
	cout << "끝말 잇기 게임을 시작합니다." << endl;
	cout << "게임에 참가하는 인원은 몇명입니까?";
	cin >> num;

	Player p(num);
	string named;

	cout << "시작 단어는 아버지 입니다." << endl;
	while( 1) {
		named = p.getName();

		cout << named << ">>";
		getline( cin, after);

		int size = before.size();
		if( before.at( size-2 ) == after.at(0) && before.at( size-1 ) == after.at(1) )
		{
			before = after;
			continue;
		}
		else 
		{
			cout << named << "이 졌습니다.";
			break;
		}
	}
}

int main() {	
	WordGame g;
	g.game();
}

 

 

4. 설명

 

Player 클래스는 게임의 참가하는 인원 수를 입력 받은만큼 string배열을 동적으로 생성합니다.

 

그 후 참가자들 각각의 이름을 입력 받는 것으로 생성자가 끝납니다.

 

number변수에는 게임의 참가하는 인원수가 저장 되어있고 temp는 현재 차례가 누군지를 저장합니다.

 

이 2변수를 사용하여서 getName()함수를 호출할 때마다 차례대로 이름을 return하도록 합니다.

 

-----

 

 

WordGame 클래스의 생성자는 시작 단어인 "아버지"를 before변수에 저장합니다.
 
멤버 함수 game()에서는 게임의 시작과 진행, 종료를 구현합니다.
 
문자를 비교하는 방법은, 한글은 한 자에 2바이트로이므로 한글을 비교하기 위해서는 2개를 비교하여야 합니다.
 
before.at( size-2 ) == after.at(0) && before.at( size-1 ) == after.at(1) 처럼 맨 before 단어 끝 2개와 맨 after 단어(현재 입력되는 단어) 처음 2개를 비교해 주어야 합니다.
 
-----
 
※  Player() 생성자 함수 구현부를 보면 참가자들의 이름을 입력 받기 전 fflush(stdin); 을 한 이유는 우선 game()함수에서 
 
cin을 사용하여서 참가자들의 수를 입력 받았습니다. 그 후 Player 변수를 선언하고 생성자로 들어가 이름을 입력 받을 시 
 
getline을 사용합니다. 하지만 여기서 fflush(stdin)이 없다면 오류가 발생합니다.
 
그 이유는 cin은 "\n"(엔터)를 입력버퍼에서 남기기 때문입니다. \n이 남아 있는 상태에서 getline()이 실행되게 되고 오류가  
발생하게 되는 것 입니다. 그러니 fflush(stdin)으로 입력 버퍼를 비워주셔야 하는 것 입니다. 또한 fflush(stdin);을 Player 
 
생성자에서 삽입하지 않고 game()함수에서 인원 수를 입력 받은 후 fflush(stdin);으로 입력 버퍼를 비운 후 Player 변수를 
 
생성하여도 오류가 발생하지 않습니다.

 

+ Recent posts