[C++] 명품C++ Programming 4장 : 실습문제

녹차·2024년 6월 20일
0

C++

목록 보기
5/11

Chapter4 문제 [13/14]

4-1

다음은 색의 3요소인 red, green, blue로 색을 추상화한 Color 클래스를 선언하고 활용하는 코드이다. 빈칸을 채워라.

red, green, blue는 0~255의 값만 가진다.

#include<iostream>
using namespace std;
 
class Color {
    int red, green, blue;
public:
    Color() {red = green = blue = 0;}
    Color(int r, int g, int b) {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); // 빨간색의 screenColor 객체 생성
    Color *p;     // Color 타입의 포인터 변수 p 선언
    _____    // (1) p가 screenColor의 주소를 가지도록 코드 작성
    _____    // (2) p와 show()를 이용하여 screenColor 색 출력
    _____    // (3) Color의 일차원 배열 colors 선언. 원소는 3개
    _____    // (4) p가 colors 배열을 가리키도록 코드 작성
    
    // (5) p와 setColor()를 이용하여 colors[0], colors[1], colors[2]가
    // 각각 빨강, 초록, 파랑색을 가지도록 코드 작성
    _____
    _____
    _____
    
    // (6) p와 show()를 이용하여 colors 배열의 모든 객체의 색 출력. for 문 이용
    _____
    _____
    _____
}
255 0 0
255 0 0
0 255 0 
0 0 255
#include<iostream> 

using namespace std;

class Color
{
	int red, green, blue;
public:
	Color() { red = green = blue = 0; }
	Color(int red, int green, int blue) { this->red = red; this->green = green; this->blue = blue; }
	void setColor(int red, int green, int blue) { this->red = red; this->green = green; this->blue = blue; }
	void show() { cout << red << ' ' << green << ' ' << blue << endl; }
};

/// <summary>
/// https://velog.io/@keunho86/C-%ED%8F%AC%EC%9D%B8%ED%84%B0
/// </summary>
void main()
{
	Color screenColor(255, 0, 0);
	Color* p; //Color 타입의 포인터 변수 p 선언
	p = &screenColor; //p가 screenColor의 주소를 가지도록 코드 작성
	p->show(); //p와 show() 이용하여 screenColor 색 출력

	Color colors[3];
	p = colors; //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();
	}
}

4-2

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

정수 5개 입력>> 1 2 4 5 10
평균 4.4
#include<iostream>

using namespace std;

/// <summary>
/// https://velog.io/@bik1111/C-%EB%8F%99%EC%A0%81%ED%95%A0%EB%8B%B9
/// </summary>
int main()
{
	int* p = new int[5]; //5개의 정수 배열동적 할당
	float sum = 0;

	cout << "정수 5개의 입력>>";

	if (!p)
		cout << "메모리를 할당할 수 없습니다.";

	for (int i = 0; i < 5; i++)
	{
		cin >> p[i];
		sum += p[i];
	}

	"\n";

	cout << "평균 " << sum / 5;

	delete []p; //소멸자
}

4-3

string 클래스를 이용하여 빈칸을 포함하는 문자열을 입력받고 문자열에서 'a'가 몇개 있는지 출력하는 프로그램을 작성해보자.

(1) 문자열에서 'a'를 찾기 위해 string 클래스의 멤버 at()나 []를 이용하여 작성하라.
(2) 문자열에서 'a'를 찾기 위해 string 클래스의 find() 멤버 함수를 이용하여 작성하라. text.find('a', index);는 text 문자열의 index 위치부터 'a'를 찾아 문자열 내 인덱스를 리턴한다.

문자열 입력>> Are you happy? i am so happy
문자 a는 3개 있습니다.

#include<iostream>
#include<string>

using namespace std;

int main()
{
	string text;
	int a_num = 0;
	int j = -1;

	cout << "문자열 입력>> ";
	getline(cin, text, '\n');

	/* (1)
	for (int i = 0; i < text.size(); i++)
	{
		if (text[i] == 'a')
		{
			a_num += 1;
		}
	}
	*/

	while (true) 
	{
		j = (int)text.find('a', j + 1); // index 0 부터 'a'를 탐색 
		
		if (j == -1) break; // 'a'를 찾지 못했으면 break 
		
		a_num++;
	}

	cout << "문자 a는 " << a_num << "개 있습니다";
}

(2) 왜 풀지 못하였는가?

(int)text.find('a', j + 1) 이 부분을 생각하지 못했다

4-4

다음과 같은 Sample 클래스가 있다.

class Sample{
    int *p;
    int size;
public:
    Sample(int n) {    // 생성자 
        size = n; p = new int [n]; // n개 정수 배열의 동적 생성
    }
    void read(); // 동적 할당받은 정수 배열 p에 사용자로부터 정수를 입력 받음 
    void write(); // 정수 배열을 화면에 출력 
    int big(); // 정수 배열에서 가장 큰 수 리턴 
    ~Sample(); // 소멸자 
};

다음 main() 함수가 실행되도록 Sample 클래스를 완성하라.

int main() {
    Sample s(10); // 10개 정수 배열을 가진 Sample 객체 생성 
    s.read(); // 키보드에서 정수 배열 읽기 
    s.write(); // 정수 배열 출력 
    cout << "가장 큰 수는 " << s.big() << endl; // 가장 큰 수 출력 
}
100 4 -2 9 55 300 44 38 99 -500
100 4 -2 9 55 300 44 38 99 -500
가장 큰 수는 300
#include<iostream>
#include<string>

using namespace std;

class Sample
{
	int* p;
	int size;
public:
	Sample(int n) {	size = n; p = new int[n]; } //n개의 정수 배열의 동적 생성
	void read(); //동적 할당받은 정수 배열 p에 사용자로부터 정수를 입력 받음
	void write(); //정수 배열을 화면에 출력
	int big(); //정수 배열에서 가장 큰 수 리턴
	~Sample(); //소멸자
};

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

int Sample::big()
{
	int bigNumber = 0;

	for (int i = 0; i < size; i++)
	{
		if (bigNumber < p[i])
		{
			bigNumber = p[i];
		}
	}

	return bigNumber;
}

Sample::~Sample() { }

int main()
{
	Sample s(10);
	s.read(); //키보드에서 정수 배열 읽기;
	s.write(); //정수 배열 출력;

	cout << "가장 큰 수는 " << s.big() << endl;
}

4-5

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

아래에 한 줄을 입력하세요.(exit를 입력하면 종료합니다)
>>Failling in love with you
Failling in love wxth you
>>hello world
hello woble
>>exit
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <string>
using namespace std;

int main() {
    string sent;
    int n;

    cout << "아래 한 줄을 입력하세요.(exit를 입력하면 종료합니다)";
    
    while (true) 
    {
        srand((unsigned)time(0));
        cout << "\n>>";
        getline(cin, sent);

        if (sent == "exit") break;
        
        int length = sent.length();
        
        //#중복 예외 처리
        while (true) 
        {
            n = rand() % length;
            if (sent[n] != ' ')
                break;
        }
        
        int a = rand() % 25 + 95; // 임의의 문자 하나 선택 
        sent[n] = (char)a;
        cout << sent;
    }
}

4-6

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

아래에 한 줄을 입력하세요.(exit를 입력하면 종료합니다)
>>ABC
CBA
>>exit
#include<iostream>
#include<string>

using namespace std;

int main()
{
	string text;

	cout << "아래에 한 줄을 입력하세요.(exit를 입력하면 종료합니다.)\n>>";

	while (true)
	{
		getline(cin, text);

		if (text == "exit")
			break;

		for (int i = text.length(); i >= 0; i--)
			cout << text[i];
	}
}

4-7

다음과 같이 원을 추상화한 Circle 클래스가 있다.

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

Circle 클래스도 완성하라.

class Circle {
    int radius; // 원의 반지름 값 
public:
    void setRadius(int radius); // 반지름을 설정한다. 
    double getArea(); // 면적을 리턴한다. 
};
원 1인 반지름 >> 5
원 2인 반지름 >> 6
원 3인 반지름 >> 7
면적이 100보다 큰 원은 2개 입니다.
#include<iostream>

using namespace std;

class Circle
{
	int r;
public:
	Circle();
	void setR(int r);
	int getR();
	double gerArea();
	~Circle();
};

Circle::Circle()
{
	r = 0;
}

void Circle::setR(int r)
{
	this->r = r;
}

int Circle::getR()
{
	return r;
}

double Circle::gerArea()
{
	return 3.14 * r * r;
}


Circle::~Circle()
{
}

int main()
{
	Circle arrCircle[3];
	int num = 0;

	for (int i = 0; i < 3; i++)
	{
		arrCircle[i].setR(5 + i);
		cout << "원 " << i + 1 << "의 반지름 >> " << arrCircle[i].getR() << endl;
	}

	for (int i = 0; i < 3; i++)
	{
		if (arrCircle[i].gerArea() > 100)
		{
			num++;
		}
	}

	cout << "면적이 10보다 큰 원은 " << num << "개 입니다";
}

4-8

실습 문제 7의 문제를 수정해보자. 사용자로부터 다음과 같이 원의 개수를 입력받고, 원의 개수만큼 반지름을 입력받는 방식으로 수정하라.

원의 개수에 따라 동적으로 배열을 할당받아야 한다.

원의 개수 입력 >> 3
원 1인 반지름 >> 5
원 2인 반지름 >> 6
원 3인 반지름 >> 7
면적이 100보다 큰 원은 2개 입니다.
#include<iostream>

using namespace std;

class Circle
{
	int r;
public:
	Circle();
	void setR(int r);
	int getR();
	double gerArea();
	~Circle();
};

Circle::Circle()
{
	r = 0;
}

void Circle::setR(int r)
{
	this->r = r;
}

int Circle::getR()
{
	return r;
}

double Circle::gerArea()
{
	return 3.14 * r * r;
}


Circle::~Circle()
{
}

int main()
{
	int inputNum;
	int rNum = 0; //면적이 100보다 큰 원의 개수

	cout << "원의 개수 >> ";
	cin >> inputNum;

	Circle* p = new Circle[inputNum];
	int* r = new int[inputNum];

	for (int i = 0; i < inputNum; i++)
	{
		cout << "원 " << i + 1 << "의 반지름 >> ";
		cin >> r[i];
		p[i].setR(r[i]);

		//cout << p[i].getR();
	}

	for (int i = 0; i < inputNum; i++)
	{
		if (p[i].gerArea() > 100)
		{
			rNum++;
		}
	}

	cout << "면적이 10보다 큰 원은 " << rNum << "개 입니다";
}

4-9

다음과 같은 Person 클래스가 있다.

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

class Person{
    string name;
    string tel;
public:
    Person();
    string getName() { return name; }
    string getTel() { return tel; }
    void set(string name, string tel);
};
이름과 전화 번호를 입력해 주세요
사람 1 >> 스폰지밥 010-0000-0000
사람 2>> 뚱이 011-1111-1111
사람 3>> 징징이 012-2222-2222
전화번호를 검색합니다. 이름을 입력하세요>>스폰지밥
전화번호는 010-0000-0000
#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) { this->name = name; this->tel = tel; };
};

Person::Person()
{
	name = "";
	tel = "";
}


int main()
{
	Person arrPerson[3];
	string name[3];
	string tel[3];
	string inputName;

	cout << "이름과 전화 번호를 입력해 주세요" << endl;

	for (size_t i = 0; i < 3; i++)
	{
		cout << "사람" << i + 1 << ">> ";
		getline(cin, name[i]);
		getline(cin, tel[i]);
		arrPerson[i].set(name[i], tel[i]);
	}

	cout << "\n모든 사람의 이름은 ";

	for (size_t i = 0; i < 3; i++)
		cout << arrPerson[i].getName();

	cout << "전화번호를 검색합니다. 이름을 입력하세요>>";
	cin >> inputName;

	for (size_t i = 0; i < 3; i++)
	{
		if (arrPerson[i].getName() == inputName)
		{
			cout << arrPerson[i].getName() << endl;
			cout << arrPerson[i].getTel();
		}
	}
}

4-10

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

class Person {
    string name;
public:
    Person(string name) { this->name = name;}
    string getName() { return name;}
};
 
class Family {
    Person *p; // Person 배열 포인터 
    int size; // Person 배열의 크기. 가족 구성원 수 
public:
    Family(string name, int size); // size 개수만큼 Person 배열 동적 생성 
    void show(); // 모든 가족 구성원 출력 
    ~Family();
};

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

int main() {
    Family *simpson = new Family("Simpson", 3); // 3명으로 구성된 Simpson 가족 
    simpson->setName(0, "Mr. Simpson");
    simpson->setName(1, "Mrs. Simpson");
    simpson->setName(2, "Bart Simpson");
    simpson->show();
    delete simpson;
}
Simpson가족은 다음과 같이 3명입니다.
Mr. Simpson Mrs...
#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; // Person 배열 포인터 
    int size; // Person 배열의 크기. 가족 구성원 수
    string name;
public:
    Family(string name, int size); // size 개수만큼 Person 배열 동적 생성
    void setName(int num, string name);
    void show(); // 모든 가족 구성원 출력 
    ~Family();
};

Family::Family(string name, int size) {
    p = new Person[size];
    this->size = size;
    this->name = name;
}

void Family::setName(int num, string name) {
    p[num].setName(name);
}

void Family::show() {
    cout << name << "가족은 다음과 같이 " << size << "명 입니다.\n";
    for (int i = 0; i < size; i++) {
        cout << p[i].getName() << "\t";
    }
}

Family::~Family() {
    delete[] p;
}

int main() {
    Family* simpson = new Family("Simpson", 3); // 3명으로 구성된 Simpson 가족 
    simpson->setName(0, "Mr. Simpson");
    simpson->setName(1, "Mrs. Simpson");
    simpson->setName(2, "Bart Simpson");
    simpson->show();
    delete simpson;
}

왜 못 풀었을까?

현 파트에서는 '상속'을 배우지 않았기 때문에 Person::setName과 Family::setName()이 같이 사용해서 구현한다는 것을 생각하지 못하였다. 좋은 문제는 아닌거 같다.

4-12

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

class Circle{
    int radius; // 원의 반지름 값 
    string name; // 원의 이름 
public:
    void setCircle(string name, int radius); // 이름과 반지름 설정 
    double getArea();
    string getName();
};
class CircleManager {
    Circle *p; // Circle 배열에 대한 포인터 
    int size; // 배열의 크기 
public:
    CircleManager(int size); // size 크기의 배열을 동적 생성. 사용자로부터 입력 완료 
    ~CircleManager();
    void searchByName(); // 사용자로부터 원의 이름을 입력받아 면적 출력 
    void searchByArea(); // 사용자로부터 면적을 입력받아 면적보다 큰 원의 이름 출력 
};

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

Circle, CircleManager 클래스도 완성하라.

원의 개수>> 4
원 1의 이름과 반지름 >> 빈대떡 10
원 2의 이름과 반지름 >> 도넛 2
원 3의 이름과 반지름 >> 초코파이 1
원 4의 이름과 반지름 >> 피자 15
검색하고자 하는 원의 이름 >> 도넛
도넛의 면적은 12.56
최소 면적을 정수로 입력하세요
10보다 큰 원을 검색합니다.
빈대떡의 면적은 314, 도넛의 면적은 12.56, 피자의 면적은 706.5,
#include <iostream>
#include <string>
using namespace std;
class Circle {
    int radius; // 원의 반지름 값
    string name; // 원의 이름
public:
    Circle(int r = 1, string name = "") { this->radius = r; this->name = name; }
    void setCircle(string name, int radius) { this->name = name; this->radius = radius; }
    double getArea() { return radius * radius * 3.14; }
    string getName() { return name; }
};


class CircleManger {
    Circle* p;  //Circle 배열에 대한 포인터
    int size;
    int radius;
    string name;
public:
    CircleManger(int size); //size 크기의 배열을 동적 생성. 사용자로부터 입력 완료
    ~CircleManger();
    void searchByName(); // 사용자로부터 원의 이름을 입력받아 면적 출력
    void searchByArea(); // 사용자로부터 면적을 입력받아 면적보다 큰 원의 이름 출력
};

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

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

void CircleManger::searchByArea()
{
    cout << "최소 면적을 정수로 입력하세요 >>";
    cin >> radius;

    cout << endl << radius << "보다 큰 원을 검색합니다.";

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

CircleManger::CircleManger(int size)
{
    p = new Circle[size];
    this->size = size;

    for (int i = 0; i < size; i++)
    {
        cout << "원 " << i + 0 << "의 이름과 반지름 >>";
        cin >> name >> radius;
        p[i].setCircle(name, radius);
    }
}

CircleManger::~CircleManger()
{
    delete[] p;
}

int main()
{
    int inputNum = 0;

    cout << "원의 개수 >> ";
    cin >> inputNum;

    CircleManger* cm = new CircleManger(inputNum);

    cm->searchByName();
}

왜 풀지 못하였는가?

CircleManager의 radius와 name을 입력받아 이를 p[i].getName()과 p[i].getradius() 접근 가능하다는걸 의식을 못했다.

4-13

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

대문자는 모두 소문자로 변환하여 처리한다.

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

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();
#include<iostream>
#include<string>

using namespace std;

class Histogram
{
	string txt;
public:
	Histogram(string txt);
	void put(string text);
	void putc(char text);
	void print();
};

Histogram::Histogram(string txt)
{
	this->txt = txt;

	cout << txt << endl;
}

void Histogram::put(string text)
{
	cout << text;
	this->txt.append(text);

}

void Histogram::putc(char text)
{
	cout << text;
}

void Histogram::print()
{
	int alp[26];
	int num = 0;
	int sum = 0; //총 알파벳 수

	//알파벳 초기화
	for (int i = 0; i < 26; i++)
		alp[i] = 0;

	//대/소문자 -> 소문자
	for (int i = 0; i < txt.size(); i++)
		txt[i] = towlower(txt[i]);

	while (num < 26)
	{
		for (int i = 0; i < txt.size(); i++) //26인 이유 -> 알파벳 개수
		{
			if (txt[i] == (char)(num + 'a'))
			{
				//#해당 알파벳 개수 추가
				alp[num]++;
				sum++;
			}
		}
		
		cout << endl << (char)(num + 'a') << " (" << alp[num] << ")    : ";

		//* 출력
		for (int i = 0; i < alp[num]; i++)
			cout << "*";

		num++;
	}

	cout << endl << "총 알파벳 수 " << sum;
}

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

출력 부분이 조금 다릅니다..

  • (char)(num + 'a') -> a부터 z 문자 출력
profile
CK23 Game programmer

0개의 댓글