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;로 동적으로 생성한 배열 변수를 해제 해주어야 합니다.

 

 

1. 문제

 

5. 다음과 같이 원을 추상화한 Circle 클래스가 있다. Circle 클래스와 main() 함수를 작성하고 3개의 Circle 객체를 가진 배열을 선언하고, 반지름 값을 입력받고 면적이 100보다 큰 원의 개수를 출력하는 프로그램을 완성하라. Circle 클래스도 완성하라.

 

 

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() {
	Circle c[3]; int r; int count=0;

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

 

 

4. 설명

 

반지름을 설정하는 setRadius(int radios);와 면적을 구하여 return하는 getArea(); 멤버 함수들을 구현 합니다.

 

 

main()에서 크기가 3인 Circle배열을 선언한 후 for문을 사용하여서 각 원의 반지름을 입력 받은 후 setRadius함수로 반지름을 저장합니다.

 

그 다음 for문과 getArea() 멤버 함수를 사용하여서 return 받은 값이 100이 넘으면 count++;을 하여서 면적이 100보다 큰 원의 개수를 구하여 총 몇개인지 출력합니다.

 

 

1. 문제

 

4. string 클래스를 이용하여 사용자가 입력한 영문 한 줄을 문자열로 입력받고 거꾸로 출력하는 프로그램을 작성하라.

 

 

2. 결과

 

 

 

3. 코드

 

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

int main() {

	string s, first, last;

	cout << "아래에 한 줄을 입력하세요.(exit를 입력하면 종료합니다)" << endl;
	while(1) {
		cout << ">>";
		getline( cin, s);
		if( s == "exit" ) break;
		int len = s.size();
		for(int i=0; i< len/2; i++ ) {
			first = s.at(i);
			last = s.at(len-1-i);
			s.replace( i, 1, last );
			s.replace( len-1-i, 1, first );
		}
		cout << s << endl;
 	}
}

 

 

4. 설명

 

string 변수 s, first, last 3개를 선언 합니다.

 

getline( cin, s)로 문자열을 입력받아 s에 저장합니다.

 

그 후 s가 "exit"가 아니라면 계속 진행하고 맞다면 break;로 while문을 종료합니다.

 

int len = s.size()로 문자열 s의 길이를 구합니다.

 

 

그 후 i=0; i< len/2; i++인 for문을 이용하여서 문자열을 반전 시킵니다.

 

->len이 홀수일 경우 len/2에서 데이터 손실이 발생하지만 가운데 글자는 옮기지 않아도 되므로 문제 없습니다.

 

first변수에는 앞쪽에서 바꿀 문자를 저장하고 last는 뒤쪽에서 바꿀 문자를 저장합니다.

 

※ s.replace( i, 1, last) : "인덱스 i부터 1개의 문자를 last로 바꾼다" 입니다.

+ Recent posts