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 변수를 
 
생성하여도 오류가 발생하지 않습니다.

 

 

 

1. 문제

 

11. 갬블링 게임을 만들어보자. 두 사람이 게임을 진행하며, 선수의 이름을 초기에 입력 받는다. 선수가 번갈아 자신의 차례에서 <Enter> 키를 치면 랜덤한 3개의 수가 생성되고 모두 동일한 수가 나오면 게임에서 이기게 된다. 숫자의 범위가 너무 크면 3개의 숫자가 일치할 가능성이 낮아 숫자의 범위를 0~2로 제한한다. 랜덤 정수 생성은 문제 3번의 힌트를 참고하라. 선수는 Player 클래스로 작성하고, 2명의 선수는 배열로 구성하라. 그리고 게임은 GamblingGame 클래스로 작성하라.

 

 

 

2. 결과

 

 

 

 

 

 

3. 코드

 

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

class Player {
	string name[2];
	int i;
public:
	Player() { i=0;}
	void setName(string namae) { name[i] = namae; i++; }
	string getName() {
		i++;
		if( i >= 2) {
			i=0;
			return name[i];
		}
		else 
			return name[i];
	}
};

class GamblingGame {
	int num[3];
public :
	GamblingGame(){ srand( (unsigned)time(0) ); }
	void Game();
};
void GamblingGame::Game() {
	cout << "***** 갬블링 게임을 시작합니다. *****" << endl;
	Player p; string name;
	cout << "첫번째 선수 이름>>";
	getline( cin, name);
	p.setName( name );
	cout << "두번째 선수 이름>>";
	getline( cin, name);
	p.setName( name );

	string named; 
	while(1) {
		named = p.getName();
		cout << named << ":<Enter>";
		getline( cin, name);
		for(int i=0; i<3; i++)
			num[i] = rand() % 3;
		cout << "\t\t" << num[0] << "\t" << num[1] << "\t" << num[2] << "\t";
		if( num[0] == num[1] && num[1] == num[2] ) {
			cout << named << "님 승리!!" << endl;
			break;
		}
		else
			cout << "아쉽군요!" << endl;
	}
}

int main() {
	GamblingGame g;
	g.Game();
}

 

 

 

4. 설명

 

Player 클래스는 선수들의 이름을 저장합니다.

 

멤버함수 setName(string name) 함수는 저장할 이름이 2명이란 것을 알고 있기 때문에 간단하게 만들었습니다.

 

또 다른 멤버함수 getName()함수는 호출할 때마다 다음 이름을 return합니다.

 

 

GamblingGame 클래스 생성자에서 srand( (unsigned)time(0) ); 을 선언하여서 실행 할 때 마다 다른 값을 구하도록 합니다.

 

멤버함수 Game()에서는 전체적인 게임이 진행되는 함수 입니다.

 

선수 이름을 각각 입력 받고 while(1)문으로 들어가 게임을 시작합니다.

 

Enter를 입력 받으 실 때는 getline으로 입력 받으셔야 합니다. cin을 사용하시면 입력 버퍼에 "\n"가 남게 되어서 오류가 발생합니다.

 

Enter를 입력 받으면 랜덤한 수 3개를 생성한 후 배열에 저장한 후 3개의 랜덤한 수를 출력합니다.

 

if문을 사용하여서 num[0] == num[1] && num[1] == num[2] 일 경우 즉, 3개의 값이 모두 같은 경우 승리하게 되고 게임이 끝나게 됩니다.

 

 

 

1. 문제

 

10. 영문자로 구성된 텍스트에 대해 각 알파벳에 해당하는 문자가 몇 개인지 출력하는 히스토그램 클래스 Histogram을 만들어보자. 대문자는 모두 소문자로 변환하여 처리한다.

 

Histogram 클래스를 활용하는 사례와 실행 결과는 다음과 같다.

 

 

2. 결과

 

 

 

3. 코드

 

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

class Histogram {
	string his;
	int len;
	int count[26];
public :
	Histogram(string h) { 
		his = h+"\n"; len = 0;
		for(int i=0; i < h.size(); i++)
			if( isalpha( his.at(i)) ) len++;
		for(int i=0; i < 26; i++)
			count[i] = 0;
	}
	void put(string h);
	void putc(char h);
	void print();
};
void Histogram::put(string h) {
	this->his += h;
	for(int i=0; i < h.size(); i++)
		if( isalpha( h.at(i)) ) len++;
}
void Histogram::putc( char h) {
	this->his += h;
	if( isalpha(h) ) len++;
}
void Histogram::print() {
	cout << his << endl << endl << "총 알파벳 수 " << len << endl << endl;
	char temp;
	for(int i=0; i < his.size(); i++) {
		if( isalpha( his.at(i) ) ) {
			temp = tolower( his.at(i) );
			count[temp-97]++;
		}
	}
	for(int i=0; i<26; i++) {
		printf("%c (%d)\t: ", 97+i, count[i]);
		for(int j=0; j < count[i]; j++)
			cout << "*";
		cout << endl;
	}
}
 
int main() {
	Histogram elvisHisto("Wise men say, only fools rush in But I Can't help, ");
	elvisHisto.put("falling in love with you");
	elvisHisto.putc('-');
	elvisHisto.put("Elvis Presley");
	elvisHisto.print();
}

 

 

4. 설명

 

생성해야할 함수들은 

Histogram(string s) : 문자열 s + "\n"를 하여서 멤버변수에 저장합니다. 또한 입력받은 알파벳의 개수를 구한다음 각 알파벳 개수를 저장할 배열 count의 모든 원소를 0으로 초기화 해줍니다.

 

void put( string s); : 저장된 문자열 뒤에 문자열 s를 추가합니다.

void put( char h); : 저장된 문자열 뒤에 문자 h를 추가합니다.

void print() : 저장된 문자열의 총 알파벳 수를 출력하고 각 알파벳의 개수를 표현하는 히스토그램을 출력합니다.

 

 

알파벳의 개수를 구해야 하므로 isalpha()를 사용하여서 알파벳인 경우 개수를 증가시켜야 합니다.

 

print()함수에서 알파벳을 출력하실 때 printf("%c (%d)\t:  ",  97+i,  count[i] ); 로 간단히 for문을 이용하여서 출력할 수 있습니다.

또한 달리 cout << (char)(i+97) << "(" << count[i] << ")\t:  "; 를 사용 하셔도 됩니다.

 

 

 

1. 문제

 

9. 다음은 이름과 반지름을 속성으로 가진 Circle 클래스와 이들을 배열로 관리하는 CurcleManager 클래스이다.

 

키보드에서 원의 개수를 입력받고, 그 개수만큼 원의 이름과 반지름을 입력받고, 다음과 같이 실해되도록 main() 함수를 작성하라. Circle, CircleManager 클래스도 완성하라.

 

 

2. 결과

 

 

 

3. 코드

 

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

class Circle {
	int radius;
	string name;
public:
	void setCircle( string name, int radius){ this->name=name; this->radius=radius; }
	double getArea(){ return radius * radius * 3.14;}
	string getName(){ return name; }
};
class CircleManager {
	Circle *p;
	int size;
public :
	CircleManager(){;}
	CircleManager(int size);
	~CircleManager(){ delete [] p;}
	void searchByName();
	void searchByArea();
};
CircleManager::CircleManager(int size) {
	string n,r;
	p = new Circle[size]; 
	this->size = size; 
	
	for(int i=0; i<size; i++) {
		 cout << "원 " << i+1 << "의 이름과 반지름 >> ";
		 cin >> n >> r;
		 p[i].setCircle( n, stoi(r) );
	 }
	fflush(stdin);
}
void CircleManager::searchByName() {
	string cir; int n;
	cout << "검색하고자 하는 원의 이름 >> ";
	getline( cin, cir);
	for(int i=0; i<size; i++)
		if( p[i].getName() == cir ) n = i;
	cout << p[n].getName() << "의 면적은 " << p[n].getArea() << endl;
}
void CircleManager::searchByArea() {
	int n;
	cout << "최소 면적을 정수로 입력하세요 >> ";
	cin >> n;
	cout << n << "보다 큰 원을 검색합니다." << endl;
	for(int i=0; i<size; i++) {
		if( p[i].getArea() > n )
			cout << p[i].getName() << "의 면적은 " << p[i].getArea() << ",";
	}
	cout << endl;
}

int main() {
	int n;
	cout << "원의 개수 >> ";
	cin >> n;
	CircleManager cm(n);
	cm.searchByName();
	cm.searchByArea();
}

 

 

4. 설명

 

Circle 클래스의 있는 함수들을 구현 합니다.

 

 

CircleManager 클래스는 매개변수가 없는 생성자와 int형 매개변수 하나를 입력받는 생성자를 생성하여서 입력받은 값의 크기만큼 Circle 배열 변수를 동적으로 생성합니다.

 

 

여기 생성자에서 각 원의 이름과 반지름을 입력 받은 후 fflush(stdin);을 하는 이유는 cin으로 입력받아서 입력 버퍼에 '\n가 남은 상태에서 다음 원의 이름을 검색 받는데 입력 버퍼에 '\n' 가 남아있어서 오류가 납니다.

 

그래서 fflush(stdin);으로 입력버퍼를 비워줍니다. 이 방법은 C에서 사용하는 방법 입니다.

 

그 외 이름을 입력받고 면적을 출력해주는 searchByName()함수와

 

정수 하나를 입력 받은 후 그 정수보다 면적이 큰 원들의 이름과 면적을 출력하는 searchByArea() 함수를 구현하면 됩니다.

 

 

 

1. 문제

 

8. 다음에서 Person은 사람을, Family는 가족을 추상화한 클래스로서 완성되지 않은 클래스이다.

 

다음 main()이 작동하도록 Person과 Family 클래스에 필요한 멤버들을 추가하고 코드를 완성하라.

 

 

2. 결과

 

 

 

3. 코드

 

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

class Person {
	string name;
public :
	Person(){;}
	Person( string name) { this->name = name; }
	string getName() { return name; }
	void setname(string name) { this->name = name; }
};

class Family {
	Person *p;
	int size;
	string name;
public : 
	Family( string name, int size) { 
		p = new Person[size]; 
		this->size = size; 
		this->name =name; 
	}
	void setName(int n, string name) { p[n].setname( name ) ;}
	void show();
	~Family(){ delete [] p; }
};
void Family::show() {
	cout << name << "가족은 다음과 같이 " << size << "명 입니다." << endl;
	for(int i=0; i<size; i++)
		cout << p[i].getName() << "\t";
	cout << endl;
}

int main() {
	Family *simpson = new Family("Simpson", 3);
	simpson->setName(0, "Mr. Simpson");
	simpson->setName(1, "Mrs. Simpson");
	simpson->setName(2, "Bart Simpson");
	simpson->show();
	delete simpson;
}

 

 

4. 설명

 

main()함수에서 Family함수를 동적으로 생성하면 Family 생성자에서 성을 입력받고, 또한 입력받은 크기만큼 Person 배열을 동적으로 생성합니다.

 

Family클래스에서 Person 배열 변수를 동적 생성하므로 Person함수의 Person() 기본 생성자를 선언하셔야 합니다.

=>이미 매개변수가 있는 Person() 생성자 때문에 디폴트 생성자 생성이 안됩니다.

 

그 후 setName() 멤버함수를 불러서 가족 구성원의 이름들을 저장 합니다.

=>여기서 동적으로 변수를 생성하였으므로 함수에 접근하기 위해서는 "->"를 사용합니다.

 

Family클래스 소멸자에서는 클래스 내에서 동적으로 생성하였던 Person 배열 변수를 delete 해주어야 합니다.

 

main()함수에서는 동적으로 생성한 Family 변수를 delete 해주어야 합니다.

 

 

1. 문제

 

7. 다음과 같은 Person 클래스가 있다. Person 클래스와 main() 함수를 작성하여, 3개의 Person 객체를 가지는 배열을 선언하고, 다음과 같이 키보드에서 이름과 전화번호를 입력받아 출력하고 검색하는 프로그램을 완성하라.

 

 

 

2. 결과

 

 

 

3. 코드

 

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

class Person {
	string name;
	string tel;
public :
	string getName() { return name; }
	string getTel() { return  tel; }
	void set( string name, string tel) { this->name = name; this->tel = tel; }
};

int main() {
	int n;
	Person p[3];
	string name, number;

	cout << "이름과 전화 번호를 입력해 주세요" << endl;
	for(int i=0; i<3; i++) {
	cout << "사람 " << i+1 << ">> ";
	cin >> name >> number;
	p[i].set( name, number);
	}
	cout << "모든 사람의 이름은 ";
	for(int i=0; i<3; i++)
		cout << p[i].getName() << " ";

	cout << endl << "전화번호를 검색합니다. 이름을 입력하세요>>";
	cin >> name;
	for(int i=0; i<3; i++)
		if( p[i].getName() == name ) n = i;
	cout << "전화 번호는 " << p[n].getTel() << endl;
}

 

 

4. 설명

 

main함수에서 Person 크기가 3인 배열 변수를 선언 합니다.

 

그리고 for문을 이용하여서 3명 각각의 이름과 전화 번호를 입력 받은 후 set()멤버 함수로 이름과 전화 번호를 저장합니다.

 

그리고 저장된 이름들을 한번 출력한다음 그 중 검색할 이름을 입력 받습니다.

 

입력 받은 이름과 같은 이름을 비교하여서 같으면 그 사람의 전화 번호를 출력합니다.

 

 

 

1. 문제

 

6. 실습 문제 5의 문제를 수정해보자. 사용자로부터 다음과 같이 원의 개수를 입력받고, 원의 개수만큼 반지름을 입력받는 방식으로 수정하라. 원의 개수에 따라 동적으로 배열을 할당받아야 한다.

 

 

 

 

2. 결과

 

 

 

3. 코드

 

#include <iostream>
using namespace std;

class Circle {
	int radius;
public :
	void setRadius(int radius);
	double getArea();
};
void Circle::setRadius(int radius) {
	this->radius = radius;
}
double Circle::getArea() {
	return radius * radius * 3.14;
}

int main() {
	int num; int r; int count=0; 
	
	cout << "원의 개수 >> ";
	cin >> num;
	Circle *c = new Circle[num];

	for(int i=0; i<num; i++) {
		cout << "원 " << i+1 << "의 반지름 >> ";
		cin >> r;
		(c+i)->setRadius(r);
	}
	for(int i=0; i<num; i++)
		if( (c+i)->getArea() > 100 ) count++;
	
	cout << "면적이 100보다 큰 원은 " << count << "개 입니다" << endl;

	delete [] c;
}

 

4. 설명

 

생성할 원의 개수를 입력받은 후 입력받은 개수만큼 Circle 배열 변수를 동적으로 생성합니다.

 

 

그 후 5번에서 구현했던 setRadius()함수로 반지름을 저장합니다.

 

그 다음 5번처럼 getArea()로 return 받은 값이 100보다 크다면 count++로 넓이가 100이 넘는 원의 개수를 구한 다음 출력 합니다.

 

※ "(c+i)->"말고 "c[i]."로 멤버함수의 접근하여도 무관 합니다. 단 배열을 동적으로 생성했으므로 delete [] c;로 동적으로 생성한 배열 변수를 해제 해주어야 합니다.

+ Recent posts