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

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


template <class T> T biggest(T *a, int size) {
	if (size <= 0)
    	return 0;

	T big = *a;
	for (int i = 1; i < size; i++) {
		if (big < a[i])
			big = a[i];
	}
	return big;
}

int main() {
	int i[] = { 1, 10, 100, 5 ,4 };
	double d[] = { 1.1, 15.8, 55.2 };
	string s[] = { "i wnat", "them", "first", "second", "somet imes"};
	cout << biggest(i, 5) << endl;
	cout << biggest(d, 3) << endl;
	cout << biggest(s, 5) << endl;
}

2. 두 개의 배열을 비교하여 같으면 true 를,아니면 false 를 리턴하는 제네릭 함수 equalArrays() 를 작성하라. 또한 main() 함수를 작성하여 equalArrays( ) 를 호출 하는 몇 가지 사례를 보여라. equalArrays( ) 를 호출하는 코드 사례는 다음과 같다.

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

template <class T> 
bool equalArrays(T* arr1, T*arr2, int size) {

	for (int i = 0; i < size; i++) {
		if (arr1[i] != arr2[i]) return false;
	}

	return true;
}

int main() {
	int x[] = { 1,10,100,5,4 };
	int y[] = { 1,10,100,5,4 };
	if (equalArrays(x, y, 4))
		cout << "같다" << endl;
	else
		cout << "다르다" << endl;

	double a[] = {1.7, 2.4, 8.8, 99, 509.8 };
	double b[] = { 1.7, 2.4, 8.8, 99, 509.8 };
	if (equalArrays(a, b, 5))
		cout << "같다" << endl;
	else
		cout << "다르다" << endl;

}

 


3.  배열의 원소를 반대 순서로 뒤집는 revreseArray() 함수를 템플릿으로 작성하라. reverseArray( ) 의 첫 번째 매개 변수는 배열에 대한 포인터이며 두 번째 매개 변수는 배열의 개수이다. reverseArray( ) 의 호출 사례는 다음과 같다.  (배열의 원소를 반대로 뒤집을 때 반복을 size 만큼 하는게 아니라 size /2 만큼 해야한다)

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


template <class T>
void reverseArray(T* arr, int size) {
	T tmp;
	for (int i = 0; i < size / 2; i++) {
		tmp = arr[i];
		arr[i] = arr[size - i - 1];
		arr[size - i - 1] = tmp;
	}
}

int main() {
	int x[] = { 1,10,100,5,4 };
	double b[] = { 1.7, 2.4, 8.8, 99, 509.8 };

	reverseArray(x, 5);
	reverseArray(b, 5);

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

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

4. 배열에서 원소를 검색하는 search() 함수를 템플릿으로 작성하라. search( ) 의 첫 번째 매개 변수는 검색하고자 하는 원소 값이고,두 번째 매개 변수는 배열이며, 세 번 째 매개 변수는 배열의 개수이다. search() 함수가 검색에 성공하면 tru e 를,아니면 false 를 리턴한다. search( ) 의 호출 사례는 다음과 같다.

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

template <class T>
bool search(T data, T* arr, int size) {
	for (int i = 0; i < size; i++) {
		if (arr[i] == data) 
			return true;
	}
	return false;
}

int main() {
	int x[] = { 1,10, 100, 5,4 };
	if (search(100, x, 5))
		cout << "100이 배열 x에 포함되어 있다" << endl;
	else
		cout << "100이 배열 x에 포함되어 있지 않다" << endl;
}

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

( 두번째 배열을 연결 할때 주의, 마지막 main() 함수에서 메모리 할당 반환)

 

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

template <class T> 
T* concat(T* a, int sizea, T* b, int sizeb) {
	T* c = new T[sizea + sizeb];
	if (!c) {
		cout << "동적할당 실패";
		exit(1);
	}

	for (int i = 0; i < sizea; i++) {
		c[i] = a[i];
	}
	for (int i = 0; i < sizeb; i++) {
		c[sizea + i] = b[i];
	}

	return c;
}

int main() {
	int a[] = { 1,2,3,4,5,6 };
	int b[] = { 7,8,9,10, 11 };
	int* c = concat(a, 6, b, 5);
	for (int i = 0; i < 11; i++) {
		cout << c[i] << ' ';
	}

	cout << endl;
	delete[] c;


	char x[] = { 'L', 'o', 'v', 'e' };
	char y[] = { 'C', '+', '+' };
	char* q = concat(x, 4, y, 3);
	for (int i = 0; i < 7; i++)
		cout << q[i] << ' ';

	cout << endl;
	delete[] q;
}

6. 다음 함수는 매개 변수로 주어진 int 배열 src 에서 배열 minus에 들어있는 같은 정수를 모두 삭제한 새로운 int 배열을 동적으로 할당받아 리턴한다. retSize 는 remove() 함수의 실행 결과를 리턴하는 배열의 크기를 전달받는다.

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

template <class T>
T* remove(T* src, int sizeSrc, T* minus, int sizeMinus, int& retSize) {
	retSize = sizeSrc;
	for (int i = 0; i < sizeSrc; i++) {
		for (int j = 0; j < sizeMinus; j++) {
			if (src[i] == minus[j]) {
				retSize--;
				break;
			}
		}
	}

	T *p = new(nothrow) T[retSize];
	if (!p) {
		cout << "동적할당 실패" << endl;
		exit(1);
	}

	
	int index = 0;
	for (int i = 0; i < sizeSrc; i++) {
		bool isExist = false;
		for (int j = 0; j < sizeMinus; j++) {
			if (src[i] == minus[j]) {
				isExist = true;
				break;
			}
		}
		if (!isExist) {
			p[index++] = src[i];
		}

	}

	return p;
}

int main() {
	int src[] = { 1, 2, 3, 4, 5, 6 };
	int minus[] = { 2, 4, 6 };
	int sizeSrc = 6;
	int sizeMinus = 3;
	int retSize;

	int* result = remove(src, sizeSrc, minus, sizeMinus, retSize);

	for (int i = 0; i < retSize; i++) {
		cout << result[i] << ' ';
	}
	cout << endl;

	delete[] result;
	return 0;
}

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

주어진 문제의 오류는 main() 함수의 다음 라인에서 비롯된다.
y = bigger(waffle, pizza);

이 호출을 위해, bigger 템플릿을 Circle 타입으로 구체화하면 다음과 같이 된다.
Circle bigger(Circle a, Circle b) {
if(a > b) return a; 
else return b;
}

그렇지만 이 코드에서 if(a > b)문의 연산자 > 가 작성 되어 있지 않기 때문에,
컴파일 오류가 발생한다.
이 문제를 해결하기 위해, 이 정답에서는 Circle bigger(Circle a, Circle b);의 함수를
따로 중복 작성한다.

 

7 -2 ) 아래 결과와 같이 출력되도록 프로그램을 수정하라

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

 


8. 문제 7을 푸는 다른 방법을 소개한다. bigger() 함수의 다음 라인에서 > 연산자 때문에4

if (a > b) return a;

T에 Circ e 과 같은 클래스 타입이 대입되면, 구체화가 실패하여 컴파일 오류가 발생 한다. 이 문제를 해결하기 위해 다음과 같은 추상 클래스 Comparable을 제안한다.

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

Circle 클래스가 Comparable을 상속받아 순수 가상 함수를 모두 구현하면, 앞의 bigger() 템플릿 함수를 사용하는데 아무 문제가 없다. C irc le 뿐 아니라, Comparable 을 상속받은 모든 클래스를 b ig g e r( ) 에 사용할 수 있다. comparable을 상속받은 Circ le 클래스를 완성하고 문제 7의 main( ) 을 실행하여 테스트 하라. (하.. 어떻게 하는지 모르겠다)

#include <iostream>
using namespace std;

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


class Circle: public Comparable {
	int radius;
public:
	Circle(int radius = 1) { this->radius = radius; }
	int getRadius() { return radius; }
	bool operator > (Comparable& op2);
	bool operator < (Comparable& op2);
	bool operator == (Comparable& op2);
};


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

 


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

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

int main() {
	vector<int> v;
	int n;
	while (true) {
		cout << "정수를 입력하세요(0을 입력하면 종료)>>";
		cin >> n;
		if (n == 0) break;
		v.push_back(n);
		
		int sum = 0;
		for (int i = 0; i < v.size(); i++) {
			cout << v[i] << " ";
			sum += v[i];
		}
		cout << endl;
		cout << "평균 = " << (double)sum / v.size() << endl;

	}
}

 

수정 후 

grade.h

#ifndef GRADE_H
#define GRADE_H
#include <string>
#include <map>
using namespace std;

class GradeManager {
	string program;
	map<string, int> scoreMap;
	void insert();
	void search();
	bool checkInputError();
public:
	GradeManager(string program);
	void run();
};
#endif

 

grade.cpp

#include <iostream>
#include <string>
#include <map>
#include "grade.h"
using namespace std;

GradeManager::GradeManager(string program) {
	this->program = program;
}

bool GradeManager::checkInputError() {
	if (cin.fail()) {
		cin.clear();
		cin.ignore(100, '\n');
		cout << "입력 오류" << endl;
		return true;

	}
	else return false;
}

void GradeManager::insert() {
	string name;
	int score;

	while (true) {
		cout << "이름과 점수>>";
		cin >> name >> score;

		if (checkInputError()) continue;

		if (scoreMap.find(name) != scoreMap.end()) {
			cout << name << "의 점수를 수정할 수 없음" << endl;
			break;
		}

		scoreMap.insert(make_pair(name, score));
		break;
	}
}

void GradeManager::search() {
	string name;
	int score;
	cout << "이름 >>";
	cin >> name;
	if (scoreMap.find(name) == scoreMap.end())
		cout << "찾을 수 없는 이릅입니다." << endl;
	else {
		score = scoreMap[name];
		cout << name << "의 점수는" << score << endl;
	}
}



void GradeManager::run() {
	int sel;
	cout << "**** 점수관리 프로그램" << program << "을 시작합니다. *****" << endl;
	while (true) {
		cout << "입력:1, 조회:2, 종료:3 >>";
		cin >> sel;
		if (checkInputError()) continue;

		switch (sel) {
		case 1:
			insert();
			break;

		case 2:
			search();
			break;

		case 3:
			cout << "프로그램을 종료합니다..." << endl;
			return;
		}
	}
}

 

mani.cpp

#include "grade.h"

int main() {
	GradeManager grade("HIGH SCORE");
	grade.run();
}

14.

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

class Secret {
	string program;
	map<string, string> secretMap;
	void insert();
	void check();
	bool checkInputError();
public:
	Secret(string program);
	void run();
};

Secret::Secret(string program) {
	this->program = program;
}

bool Secret::checkInputError() {
	if (cin.fail()) {
		cin.clear();
		cin.ignore(100, '\n');
		cout << "입력오류" << endl;
		return true;
	}
	else return false;
}

void Secret::insert() {
	string name, pass;
	while (true) {
		cout << "이름 암호>>";
		cin >> name>>  pass;
		if (checkInputError()) continue;

		if (secretMap.find(name) != secretMap.end()) {
			cout << name << "의 암호는 수정할 수 없습니다." << endl;
			break;
		}
		secretMap[name] = pass;
		break;
	}
}

void Secret::check() {
	string name, pass, user;
		cout << "이름?";
		cin >> name;
		if (secretMap.find(name) == secretMap.end()) 
			cout << "저장되지 않은" << name << "입니다." << endl;		
		else {
			pass = secretMap[name];

			while (true) {
				cout << "암호?";
				cin >> user;
				if (pass == user) {
					cout << "통과!!" << endl;
					break;
				}
				else {
					cout << "실패~~" << endl;
				}
			}
		}
}

void Secret::run() {
	int sel;
	cout << "***** 암호 관리 프로그램 " << program << "를 시작합니다. *****" << endl;
	while (true) {
		cout << "삽입:1, 검사:2, 종료:3>>";
		cin >> sel;
		if (checkInputError()) continue;
		switch (sel) {
		case 1: insert(); break;
		case 2: check(); break;
		case 3: 
			cout << "프로그램을 종료합니다..." << endl;
			return;
		}
	}
}

int main() {
	Secret secret("WHO");
	secret.run();
}

+ Recent posts