C++/PS

[C++ PS] 명품 C++ Programming 실습 문제 4장 풀이

Song 컴퓨터공학 2023. 7. 7. 18:40

명품 C++ Programming 교재 4장 객체 포인터와 객체 배열, 객체의 동적 생성 실습문제 풀이입니다. 개인 풀이이므로 더 효율적인 풀이가 있을 수는 있으나 문제에서 요구하는 출력 조건은 모두 맞춘 해답 코드입니다.

 

 

1. Color 클래스를 선언하고 활용하는 코드를 완성시켜라. red, green, blue 는 0 ~ 255의 값만 가진다.

// 실습 1번
#include <iostream>
using namespace std;

class Color {
	int red, green, blue;
public:
	Color(int r = 0, int g = 0, int b = 0) { red = r; green = g; blue = b; }
	void setColor(int r, int g, int b) { red = r; green = g; blue = b; }
	void show() { cout << red << ' ' << green << ' ' << blue << endl; }
};

int main()
{
	Color screenColor(255, 0, 0);
	Color* p = &screenColor;
	p->show();
	Color colors[3];
	p = colors;

	p[0].setColor(255, 0, 0);
	p[1].setColor(0, 255, 0);
	p[2].setColor(0, 0, 255);

	for (int i = 0; i < 3; i++) (p + i)->show();
}

 

 

 

2. 정수 공간 5개를 배열로 동적 할당받고, 정수를 5개 입력받아 평균을 구하고 출력한 뒤 배열을 소멸시키도록 main() 함수를 작성해라

// 실습 2번
#include <iostream>
using namespace std;

int main()
{
	int* p = new int[5];
	int sum = 0;
	cout << "정수 5개 입력 >> ";
	for (int i = 0; i < 5; i++)
	{
		cin >> p[i];
		sum += p[i];
	}
	cout << "평균 : " << (double)sum / 5 << endl;
	delete[] p;
}

 

 

 

3. string 클래스를 이용하여 빈칸을 포함하는 문자열을 입력받고 문자열에서 'a'가 몇 개 있는지 출력하는 프로그램을 작성하라. 또한 find() 를 사용해 'a'의 인덱스를 출력하라

// 실습 3번
#include <iostream>
#include <string>
using namespace std;

int main()
{
	string s;
	int count = 0;
	cout << "문자열 입력 >> ";
	getline(cin, s, '\n');

	for (int i = 0; i < s.size(); i++) {
		if (s.at(i) == 'a') count++;
	}
	cout << "문자 a는 " << count << "개 있습니다." << endl;

	// (2)번. find() 멤버 함수 이용하여 a의 인덱스를 작성하기
	int index = 0;
	cout << "a의 인덱스 : ";
	while ((index = s.find('a', index)) != -1) {
		cout << index << ' ';
		index++;
	}

	return 0;
}

 

 

 

4. Sample 클래스를 완성하라. 

// 실습 4번
#include <iostream>
using namespace std;
class Sample {
	int* p; int size;
public:
	Sample(int n) {
		size = n;
		p = new int[n];
	}
	void read();
	void write();
	int big();
	~Sample() { delete[] p; }
};

void Sample::read() {
	for (int i = 0; i < size; i++) cin >> p[i];
}

void Sample::write() {
	for (int i = 0; i < size; i++) cout << p[i] << " ";
	cout << endl;
}

int Sample::big()
{
	int max = -100000;
	for (int i = 0; i < size; i++)
	{
		if (p[i] > max) max = p[i];
	}
	return max;
}

int main() {
	Sample s(10);
	s.read();
	s.write();
	cout << "가장 큰 수는 " << s.big() << endl;
}

 

 

 

5. string 클래스를 이용해 사용자가 입력한 영문 한 줄을 입력받고 글자 하나만 랜덤하게 수정하여 출력하는 프로그램을 작성하라.

// 실습 5번
#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
using namespace std;

int main()
{
	srand((unsigned)time(NULL));
	string s;
	cout << "아래에 한 줄을 입력하세요.(exit를 입력하면 종료합니다)" << endl;
	do {
		cout << ">>";
		getline(cin, s, '\n');
		if (s == "exit") break;
		s[rand() % s.size()] = 97 + rand() % 26;
		cout << s << endl;
	} while (1);
}

 

 

 

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

// 실습 6번
#include <iostream>
#include <string>
using namespace std;

int main()
{
	string s;
	cout << "아래에 한 줄을 입력하세요.(exit를 입력하면 종료합니다)" << endl;
	do {
		cout << ">>";
		getline(cin, s, '\n');
		if (s == "exit") break;

		for (int i = s.size(); i >= 0; i--) cout << s[i];
		cout << endl;
	} while (1);
}

 

 

 

7. Circle 클래스를 완성하여 반지름 값을 입력받고 면적이 100보다 큰 원의 개수를 출력하는 프로그램을 완성하라.

// 실습 7번
#include <iostream>
using namespace std;

class Circle {
private:
	int radius;
public:
	void setRadius(int radius);
	double getArea();
};

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

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

 

 

 

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

// 실습 8번
#include <iostream>
using namespace std;

class Circle {
private:
	int radius;
public:
	void setRadius(int radius);
	double getArea();
};

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

int main()
{	
	int n;
	cout << "원의 개수 >> ";
	cin >> n;

	Circle* p = new Circle[n];
	int temp, count = 0;
	for (int i = 0; i < n; i++) {
		cout << "원 " << i + 1 << "의 반지름 >> ";
		cin >> temp;
		(p + i)->setRadius(temp);
		if ((p + i)->getArea() > 100) count++;
	}
	cout << "면적이 100보다 큰 원은 " << count << "개 입니다" << endl;
	delete[] p;
}

 

 

 

9. Person 클래스를 참고하여 3개의 Person 객체를 가지는 배열을 선언하고, 프로그램을 완성해라.

// 실습 9번
#include <iostream>
#include <string>
using namespace std;

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

Person::Person() { name[0] = NULL; tel[0] = NULL; }
void Person::set(string name, string tel) {
	this->name = name;
	this->tel = tel;
}

int main()
{
	Person p[3];
	string name;
	string tel;
	cout << "이름과 전화 번호를 입력해주세요" << endl;
	for (int i = 1; i < 4; i++) {
		cout << "사람 " << i << ">> ";
		cin >> name >> tel;
		p[i - 1].set(name, tel);
	}
	cout << "모든 사람의 이름은 " << p[0].getName() << ' ' << p[1].getName() << ' ' << p[2].getName() << endl;
	cout << "전화번호 검색합니다. 이름을 입력하세요>> ";
	cin >> name;
	int index;
	for (int i = 0; i < 3; i++) {
		if (name == p[i].getName()) {
			index = i;
			break;
		}
	}
	cout << "전화 번호는 " << p[index].getTel();
}

 

 

 

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

// 실습 10번
#include <iostream>
#include <string>
using namespace std;

class Person {
	string name;
public:
	Person() { name[0] = NULL; }
	Person(string name) { this->name = name; }
	void setName(string name) { this->name = name; }
	string getName() { return name; }
};

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

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;
}

 

 

 

11. 커피자판기로 동작하는 프로그램을 완성하라. 만일 커피, 물, 설탕 중 잔량이 하나라도 부족해 커피를 제공할 수 없는 경우 '원료가 부족합니다'를 출력하라.

// 실습 11번
#include <iostream>
#include <string>
using namespace std;


class Container {
	int size;
public:
	Container() { size = 10; }
	void fill() { size = 10; }
	void consume() {
		if (size <= 0) {
			cout << "원료가 부족합니다." << endl;
			return;
		}
		else
			size--;
	}
	int getSize() { return size; }
};

class CoffeeVendingMachine {
private:
	Container tong[3];
	void fill() {
		for (int i = 0; i < 3; i++) this->tong[i].fill();
		show();
	}
	void selectEspresso();
	void selectAmericano();
	void selectSugarCoffee();
	void show() { cout << "커피 " << tong[0].getSize() << ", 물 " << tong[1].getSize() << ", 설탕 " << tong[2].getSize() << endl; }
public:
	void run() {
		cout << "***** 커피 자판기를 작동합니다. *****" << endl;
		int sel;
		while (1) {
			cout << "메뉴를 눌러주세요(1:에스프레소, 2:아메리카노, 3:설탕커피, 4:잔량보기, 5:채우기)>> ";
			cin >> sel;
			switch (sel) {
			case 1:
				selectEspresso();
				break;
			case 2:
				selectAmericano();
				break;
			case 3:
				selectSugarCoffee();
				break;
			case 4:
				show();
				break;
			case 5:
				fill();
				break;
			default:
				cout << "다시 입력해주세요" << endl;
			}
		}
	}
};

void CoffeeVendingMachine::selectEspresso() {
	if (tong[0].getSize() >= 1 && tong[1].getSize() >= 1) {
		tong[0].consume();
		tong[1].consume();
		cout << "에스프레소 드세요" << endl;
	}
	else {
		cout << "원료가 부족합니다" << endl;
	}
}
void CoffeeVendingMachine::selectAmericano() {
	if (tong[0].getSize() >= 1 && tong[1].getSize() >= 2) {
		tong[0].consume();
		tong[1].consume();
		tong[1].consume();
		cout << "아메리카노 드세요" << endl;
	}
	else {
		cout << "원료가 부족합니다" << endl;
	}
}
void CoffeeVendingMachine::selectSugarCoffee() {
	if (tong[0].getSize() >= 1 && tong[1].getSize() >= 2 && tong[2].getSize() >= 1) {
		tong[0].consume();
		tong[1].consume();
		tong[1].consume();
		tong[2].consume();
		cout << "설탕커피 드세요" << endl;
	}
	else {
		cout << "원료가 부족합니다" << endl;
	}
}

int main()
{

	CoffeeVendingMachine cm;
	cm.run();
	return 0;
}

 

 

 

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

// 실습 12번
#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 3.14 * radius * radius; }
	string getName() { return name; }
};

class CircleManager {
	Circle* p;
	int size;
public:
	CircleManager(int size) { p = new Circle[size]; this->size = size; }
	~CircleManager() { delete[] p; }
	Circle* getCircle() { return p; }
	void searchByName();
	void searchByArea();
};

void CircleManager::searchByName() {
	string find;
	cout << "검색하고자 하는 원의 이름 >> ";
	cin >> find;

	for (int i = 0; i < size; i++) {
		if (find == p[i].getName()) {
			cout << p[i].getName() << "의 면적은 " << p[i].getArea() << endl;
			break;
		}
	}
}
void CircleManager::searchByArea() {
	int minArea;
	cout << "최소 면적을 정수로 입력하세요 >> ";
	cin >> minArea;
	cout << minArea << "보다 큰 원을 검색합니다." << endl;

	for (int i = 0; i < size; i++) {
		if (p[i].getArea() > minArea) {
			cout << p[i].getName() << "의 면적은 " << p[i].getArea() << ", ";
		}
	}
	cout << endl;
}

int main() {
	int numOfCircles;
	cout << "원의 개수 >> ";
	cin >> numOfCircles;

	CircleManager circles(numOfCircles);

	for (int i = 0; i < numOfCircles; i++) {
		cout << "원 " << i + 1 << "의 이름과 반지름 >> ";
		string name;
		int r;
		cin >> name >> r;
		circles.getCircle()[i].setCircle(name, r);
	}
	circles.searchByName();
	circles.searchByArea();

	return 0;
}

 

 

 

13. 영문자로 구성된 텍스트에 대해 각 알파벳에 해당하는 문자가 몇 개인지 출력하는 히스토그램 클래스 Histogram 을 만들어라.

// 실습 13번
#include <iostream>
#include <string>
#include <cstring>
using namespace std;

class Histogram {
	string str;
	int alphabet[26] = { 0 };
public:
	Histogram(string str) { this->str = str; }
	void put(string new_str) { this->str.append(new_str); }
	void putc(char ch) { this->str.append(&ch); }
	void print();
	int getAlphabetSize();
	void countAlphabet();
};

void Histogram::print() {
	cout << str << endl << endl;
	cout << "총 알파벳 수 " << getAlphabetSize() << endl << endl;

	countAlphabet();
	char ch = 'a';
	while (ch <= 'z') {
		cout << ch << " (" << alphabet[(int)ch - 'a'] << ")\t: ";
		for (int i = 0; i < alphabet[(int)ch - 'a']; i++) {
			cout << "*";
		}
		cout << endl;
		ch++;
	}
}

int Histogram::getAlphabetSize() {
	int cnt = 0;
	for (int i = 0; i < str.length(); i++) {
		if ((str[i] >= 'a' && str[i] <= 'z') || (str[i] >= 'A' && str[i] <= 'Z')) {
			cnt++;
		}
	}
	return cnt;
}


void Histogram::countAlphabet() {
	for (int i = 0; i < str.length(); i++) {
		if (str[i] >= 'A' && str[i] <= 'Z') {
			int ind = str[i] - 'A';
			alphabet[ind]++;
		}
		if (str[i] >= 'a' && str[i] <= 'z') {
			int ind = str[i] - 'a';
			alphabet[ind]++;
		}
	}
}

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();

	return 0;
}

 

 

 

14. 갬블링 게임을 만들어라. 두 사람이 게임을 진행하며, 선수의 이름을 초기에 입력 받는다. 선수가 번갈아가며 자신의 차례에 <Enter> 키를 치면 랜덤한 수가 생성되고 모두 동일한 수가 나오면 게임에서 이기게 된다. 숫자의 범위는 0 ~ 2. 선수는 Player 클래스로 작성하고 2명의 선수는 배열로 구성, 게임은 GamblingGame 클래스로 작성해라.

// 실습 14번
#include <iostream>
#include <string>
#include <ctime>
#include <cstdlib>

using namespace std;

class Player {
	int card[3];
	string name;
public:
	Player() :Player("플레이어") { }
	Player(string name) { this->name = name; }
	string getName() { return name; }
	bool playGambling();
};
bool Player::playGambling() {
	for (int i = 0; i < 3; i++) {
		card[i] = rand() % 3;
		cout << "\t" << card[i];
	}
	for (int i = 0; i < 2; i++) {
		if (card[i] != card[i + 1]) {
			return false;
		}
	}
	return true;
}

class GamblingGame {
	Player player[2];
	bool isGameCompleted = false;
public:
	GamblingGame();
	void play();
};

GamblingGame::GamblingGame() {
	cout << "*****갬블링 게임을 시작합니다. *****" << endl;
	string name;
	cout << "첫번째 선수 이름>>";
	cin >> name;
	player[0] = Player(name);
	cout << "두번째 선수 이름>>";
	cin >> name;
	player[1] = Player(name);
	getchar();
}

void GamblingGame::play() {
	int i = 0;
	while (!isGameCompleted) {
		cout << player[i % 2].getName() << ":<Enter>";
		getchar();
		if (player[i % 2].playGambling()) {
			isGameCompleted = true;
			cout << "\t" << player[i % 2].getName() << "님 승리!!" << endl;
		}
		else {
			cout << "\t아쉽군요!" << endl;
		}
		i++;
	}
}

int main() {
	GamblingGame game;
	game.play();

	return 0;
}