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

녹차·2024년 7월 2일
0

C++

목록 보기
11/11

Chapter10 문제 [12/16]

10-1

배열을 받아 가장 큰 값을 리턴하는 제네릭 함수 biggest()를 작성하라. 또한 main() 함수를 작성하여 biggest()를 호출하는 몇 가지 사례를 보여라.

include<iostream>

using namespace std;

template<class  T>
int biggest(T arr[], int size)
{
	int bigNum = 0;

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

	return bigNum;
}

int main()
{
	int x[] = { 1, 10, 100, 5, 4 };

	cout << biggest(x, 5) << endl;
}

10-2

두 개의 배열을 비교하여 같으면 true를, 아니면 false를 리턴하는 제네릭 함수 equalArrays()를 작성하라.

또한 main() 함수를 작성하여 equalArrays()를 호출하는 몇 가지 사례를 보여라.

equalArrays()를 호출하는 코드 사례는 다음과 같다.

int x[] = {1, 10, 100, 5, 4};
   int y[] = {1, 10, 100, 5, 4};
   if(equalArray(x, y, 5)) 
       cout << "같다"; // 배열 x, y가 같으므로 "같다" 출력 
   else
       cout << "다르다";

같다

#include<iostream>

using namespace std;

template<class  T>
bool equalArrays(T arr1[], T arr2[],int size)
{
	bool isAllequal = 0;

	for (int i = 0; i < size; i++)
	{
		if (arr1[i] == arr2[i])
			isAllequal = true;
		else
			isAllequal = false;
	}

	return isAllequal;
}

int main()
{
	int x[] = { 1, 10, 100, 5, 4 };
	int y[] = { 1, 10, 100, 5, 4 };

	if (equalArrays(x, y, 5)) 
		cout << "같다";
	else
		cout << "다르다";
}

10-3

배열의 원소를 반대 순서로 뒤집는 reverseArray() 함수를 템플릿으로 작성하라.

reverseArray()의 첫 번째 매개 변수는 배열에 대한 포인터이며 두 번째 매개 변수는 배열의 개수이다.

reverseArray()의 호출 사례는 다음과 같다.

 int x[] = { 1, 10, 100, 5, 4};
    reverseArray(x, 5);
    for(int i=0; i<5; i++)
        cout << x[i] << ' '; // 4 5 100 10 1이 출력된다. 
#include<iostream>

using namespace std;

template<class  T>
void reverseArray(T arr[], int size)
{
    T* arr2 = new T[size];

    for (int i = 0; i < size; i++)
    {
        arr2[i] = arr[size - 1 - i];
    }

    for (int i = 0; i < size; i++)
    {
        arr[i] = arr2[i];
    }
}

int main()
{
	int x[] = { 1, 10, 100, 5, 4 };

	reverseArray(x, 5);

	for (int i = 0; i < 5; i++)
	{
		cout << x[i] << ' ';
	}
}

풀지 못했던 이유

T arr2[] 

계속 오류가 발생해

T* arr2 = new T[size]; 

이와 같이 바꾸어 해결했다.

10-4

배열에서 원소를 검색하는 search() 함수를 템플릿으로 작성하라.

search()의 첫 번째 매개 변수는 검색하고자 하는 원소 값이고, 두 번째 매개 변수는 배열이며, 세 번째 매개 변수는 배열의 개수이다.

search() 함수가 검색에 성공하면 true를, 아니면 false를 리턴한다.

search()의 호출 사례는 다음과 같다.

int x[] = {1, 10, 100, 5, 4};
 if(search(100, x, 5)) cout << "100이 배열 x에 포함되어 있다"; // 이 cout 실행
 else cout << "100이 배열 x에 포함되어 있지 않다";   
#include<iostream>

using namespace std;

template<class T>
bool search(T x, T arr[], int size)
{
	bool isSearch;
	
	for (int i = 0; i < 5; i++)
	{
		if (arr[i] == x)
		{
			isSearch = true;
			break;
		}
		else
			isSearch = false;
	}

	return isSearch;
}

int main()
{
	int x[] = { 1, 10, 100, 5, 4 };

	if (search(100, x, 5))
	{
		cout << "100이 배열 x에 포함되어 있다.";
	}
	else
	{
		cout << "100이 배열 x에 포함되어 있지 않다";
	}
}

10-5

다음 함수는 매개 변수로 주어진 두 개의 int 배열을 연결한 새로운 int 배열을 동적 할당받아 리턴한다.

int * concat(int a[], int sizea, int b[], int sizeb);

concat가 int 배열뿐 아니라 다른 타입의 배열도 처리할 수 있도록 일반화하라.

#include<iostream>

using namespace std;

template<class T>
T* concat(T arr1[], int sizea, T arr2[], int sizeb)
{
	T* newArr = new T[sizea + sizeb];

	for (int i = 0; i < sizea; i++)
	{
		newArr[i] = arr1[i];
	}

	for (int i = 0; i < sizeb; i++)
	{
		newArr[i + sizea] = arr2[i];
	}

	return newArr;
}

int main()
{
	int x1[] = { 1, 2, 3, 4 };
	int x2[] = { 5, 6, 7, 8, 9 };

	int* newArr = concat(x1, 4, x2, 5);

	for (int i = 0; i < 9; i++)
 		cout << newArr[i] << ' ';
}

10-7

다음 프로그램은 컴파일 오류가 발생한다. 소스의 어디에서 왜 컴파일 오류가 발생하는가?

#include <iostream>
using namespace std;
 
class Circle {
    int radius;
public:
    Circle(int radius = 1) { this->radius = radius; }
    int getRadius() { return radius; }
};
 
template <class T>
T bigger(T a, T b) { // 두 개의 매개 변수를 비교하여 큰 값을 리턴
    if (a > b) return a;
    else return b;
}
 
int main() {
    int a = 20, b = 50, c;
    c = bigger(a, b);
    cout << "20과 50중 큰 값은 " << c << endl;
    Circle waffle(10), pizza(20), y;
    y = bigger(waffle, pizza);
    cout << "waffle과 pizza 중 큰 것의 반지름은 " << y.getRadius() << endl;
}
#include<iostream>

using namespace std;

#include <iostream>
using namespace std;

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

template <class T>
T bigger(T a, T b) { // 두 개의 매개 변수를 비교하여 큰 값을 리턴
    if (a > b) return a;
    else return b;
}

Circle bigger(Circle a, Circle b)
{
    if (a.getRadius() > b.getRadius())
    {
        return a;
    }
    else
    {
        return b;
    }
}

int main() {
    int a = 20, b = 50, c;
    c = bigger(a, b);

    cout << "20과 50중 큰 값은 " << c << endl;

    Circle waffle(10), pizza(20), y;
    y = bigger(waffle, pizza);

    cout << "waffle과 pizza 중 큰 것의 반지름은 " << y.getRadius() << endl;
}

10-8

문제 7을 푸는 다른 방법을 소개한다.

bigger() 함수의 다음 라인에서 > 연산자 때문에

if(a > b) return a;

T에 Circle과 같은 클래스 타입이 대입되면, 구체화가 실패하여 컴파일 오류가 발생한다.

이 문제를 해결하기 위해 다음과 같은 추상 클래스 Comparable을 제안한다.

class Comparable {
public:
    virtual bool operator > (Comparable& op2) = 0; // 순수 가상 함수 
    virtual bool operator < (Comparable& op2) = 0; // 순수 가상 함수
    virtual bool operator == (Comparable& op2) = 0; // 순수 가상 함수
};
#include<iostream>

using namespace std;

class Comparable
{
public:
	virtual bool operator >(Comparable& op) = 0;
	virtual bool operator <(Comparable& op) = 0;
	virtual bool operator ==(Comparable& op) = 0;
};

class Circle : public Comparable
{
	int radius;
public:
	Circle(int radius = 1) { this->radius = radius; }
	int getRadius() { return radius; }

	bool operator >(Comparable& op)
	{
		Circle newCircle = (Circle&)op;

		if (this->radius > newCircle.radius)
			return true;
		else
			return false;
	}

	bool operator <(Comparable& op)
	{
		Circle newCircle = (Circle&)op;

		if (this->radius < newCircle.radius)
			return true;
		else
			return false;
	}

	bool operator ==(Comparable& op)
	{
		Circle newCircle = (Circle&)op;

		if (this->radius == newCircle.radius)
			return true;
		else
			return false;
	}
};

template <class T>
T bigger(T a, T b) { // 두 개의 매개 변수를 비교하여 큰 값을 리턴
	if (a > b) return a;
	else return b;
}

int main() {
	int a = 20, b = 50, c;
	c = bigger(a, b);

	cout << "20과 50중 큰 값은 " << c << endl;

	Circle waffle(10), pizza(20), y;
	y = bigger(waffle, pizza);

	cout << "waffle과 pizza 중 큰 것의 반지름은 " << y.getRadius() << endl;
}

10-9

STL의 vector 클래스를 이용하는 간단한 프로그램을 작성해보자. vector 객체를 생성하고, 키보드로부터 정수를 입력받을 때마다 정수를 벡터에 삽입하고 지금까지 입력된 수와 평균을 출력한느 프로그램을 작성하라.

0을 입력하면 프로그램이 종료된다.

정수를 입력하세요(0을 입력하면 종료)>>5
5
평균 = 5
점수를 입력하세요(0을 입력하면 종료)>>12
5 12
평균 8,5

#include<iostream>
#include<vector>

using namespace std;

void avarge(vector<int> v)
{
	int sum = 0;

	for (int i = 0; i < v.size(); i++)
	{
		sum += v[i];

		cout << v[i] << ' ';
	}

	cout << endl << "평균 : " << sum / v.size() << endl;
}

int main()
{
	vector<int> v;

	int inputNum = 0;

	while (true)
	{
		cout << "정수를 입력하세요(0을 입력하면 종료)>";
		cin >> inputNum;

		if (inputNum == 0)
			break;

		v.push_back(inputNum);
		avarge(v);
	}
}

10-10, 수도 맞히기

나라의 수도 맞추기 게임에 vector를 활용해보자. 나라 이름(nation)과 수도(capital) 문자열로 구성된 Nation 클래스를 만들고, vector< Nation> v;로 생성한 벡터를 이용하여 나라 이름과 수도 이름을 삽입할 수도 있고 랜덤하게 퀴즈를 볼 수도 있다.

프로그램 내에서 벡터에 Nation 객체를 여러 개 미리 삽입하여 퀴즈를 보도록 하라.

실행 화면은 다음과 같으며, 저자는 9개 나라의 이름과 수도를 미리 프로그램에서 삽입하였다.

문자열은 string 클래스를 이용하라.

#include<iostream>
#include<vector>
#include<random>

using namespace std;

class Nation
{
	string nation;
	string capital;
public:
	Nation(string nation = "", string capital = "")
	{
		this->nation = nation;
		this->capital = capital;
	}
	string getNation() { return nation; }
	string getCapital() { return capital; }
};

int main()
{
	vector<Nation> v;
	int inputNum;
	string  nation, capital;
	int ramdomNum;
	srand(time(NULL));

	cout << "***** 나라의 수도 맞추기 게임을 시작합니다. *****" << endl;
	
	v.push_back(Nation("한국", "서울"));

	while (true)
	{
		cout << "정보 입력 : 1, 퀴즈 : 2, 종료 3 >>";
		cin >> inputNum;

		switch (inputNum)
		{
			case 1:
				cout << "현재 " << v.size() << "개의 나라가 입력되어 있습니다" << endl;
				cout << "나라와 수도를 입력하세요(no no 이면 입력 끝)" << endl;

				while (nation != "no" && capital != "no")
				{
					cout << v.size() + 1 << ">> ";
					cin >> nation >> capital;


					for (int i = 0; i < v.size(); i++)
					{
						if (v[i].getNation() == nation)
							cout << "already exits!!" << endl;
					}

					v.push_back(Nation(nation, capital));
				}
				break;
			
			case 2:
				ramdomNum = rand() % v.size();
				
				cout << v[ramdomNum].getNation() << "의 수도는?";
				cin >> capital;

				if (capital == "exit")
					break;

				if (v[ramdomNum].getCapital() == capital)
					cout << "Correct!!" << endl;
				else
					cout << "No !!" << endl;
				break;
			
			case 3:
				break;
		}
	}
}

10-11, 책 출고& 검색

책의 년도, 책이름, 저자 이름을 담은 Book 클래스를 만들고, vector< Book> v;로 생성한 벡터를 이용하여 책을 입고하고, 저자와 년도로 검색하는 프로그램을 작성하라.

#include<iostream>
#include<vector>

using namespace std;

class Book
{
	string bookname;
	string writeperson;
	int year;
public:
	Book(string bookname = "", string writeperson = "", int year = 0)
	{
		this->bookname = bookname;
		this->writeperson = writeperson;
		this->year = year;
	}
	string GetBookName() { return bookname; }
	string GetWriteperson() { return writeperson; }
	int Getyear() { return year; }
};

int main()
{
	int year;
	string bookname;
	string writeperson;

	vector<Book> v;

	cout << "입고할 책을 입력하세요. 년도에 -1을 입고를 종료합니다" << endl;

	while (true)
	{
		cout << "년도>>";
		cin >> year;

		if (year == -1)
			break;

		cout << endl;

		cout << "책이름>>";
		cin >> bookname;

		cout << endl;

		cout << "저자>>";
		cin >> writeperson;

		v.push_back(Book(bookname, writeperson, year));
	}
	
	cout << "총 입고된 책은 " << v.size() << "권입니다.";

	while (true)
	{
		cout << "검색하고자 하는 저자 이름을 입력하세요>>";
		cin >> writeperson;

		cout << endl;

		for (int i = 0; i < v.size(); i++)
		{
			if (v[i].GetWriteperson() == writeperson)
				cout << v[i].Getyear() << "년도, " << v[i].GetBookName() << v[i].GetWriteperson();
		}
	}
}

10-13

#include<iostream>
#include<map>

using namespace std;

int main()
{
	map<string, int> map;
	int inputNum;
	string name;
	int score;

	cout << "***** 점수관리 프로그램 HIGH SCORE을 시작합니다.*****" << endl;

	while (true)
	{
		cout << "입력:1, 조회:2, 종료:3 >> " << endl;
		cin >> inputNum;

		switch (inputNum)
		{
			case 1:
				cout << "이름과 점수>>";
				cin >> name >> score;

				map.insert(make_pair(name, score));
			
				cout << name << ' ' << score;

				cout << endl;
				break;

			case 2:
				cout << "이름>> ";
				cin >> name;

				if (map.find(name) != map.end())
				{
					cout << name << "의 점수는 " << score << endl;
				}
				break;

			case 3:
				break;
		}
	}
}

10-14

암호 관리 응용프로그램을 map을 이용하여 작성하라.

실행 과정은 다음과 같다.

#include<iostream>
#include<map>

using namespace std;


int main()
{
	int inputNum = 0;

	string inputName;
	string inputPW;
	map<string, string> map;

	cout << "***** 암호 관리 프로그램 WHO를 시작합니다 *****" << endl;

	while (inputNum != 3)
	{
		cout << "삽입:1, 검사;2, 종료:3>> ";
		cin >> inputNum;

		switch (inputNum)
		{
			case 1:
				cout << "이름 암호>> ";
				cin >> inputName >> inputPW;

				map.insert(make_pair(inputName, inputPW));
				break;

			case 2:
				cout << "이름? ";
				cin >> inputName;

				while (true)
				{
					if (map.find(inputName) != map.end())
					{
						cout << "암호는? ";
						cin >> inputPW;

						if (map[inputName] == inputPW)
						{
							cout << "통과!!\n";
							break;
						}
						else
						{
							cout << "실패~~\n";
						}
					}
				}
				
				break;
		}

	}
}
                                                                                         
profile
CK23 Game programmer

0개의 댓글