본문 바로가기
개인공부/C++ 기초플러스

C++ Primer 12 Exercise

by 하고싶은건많은놈 2023. 2. 19.

01

// cow.h

#ifndef XXX_H_
#define XXX_H_

class Cow
{
	private:
		char name[20];
		char * hobby;
		double weight;
	public:
		Cow();
		Cow(const char * nm, const char * ho, double wt);
		Cow(const Cow & c);
		~Cow();
		Cow & operator=(const Cow & c);
		void ShowCow() const;
};

#endif
// cow.cpp

#include "cow.h"
#include <iostream>
#include <cstring>

Cow::Cow()
{
	name[0] = '\0';
	hobby = new char[1];
	hobby[0] = '\0';
	weight = 0;
}

Cow::Cow(const char * nm, const char * ho, double wt)
{
	strcpy(name, nm);
	hobby = new char [strlen(ho) + 1];
	strcpy(hobby, ho);
	weight = wt;
}

Cow::Cow(const Cow & c)
{
	strcpy(name, c.name);
	hobby = new char[strlen(c.hobby) + 1];
	strcpy(hobby, c.hobby);
	weight = c.weight;
}

Cow::~Cow()
{
	delete [] hobby;
}

Cow & Cow::operator=(const Cow & c)
{
	if (this == &c)
		return *this;
	delete [] hobby;
	strcpy(name, c.name);
	hobby = new char[strlen(c.hobby) + 1];
	strcpy(hobby, c.hobby);
	weight = c.weight;
	return *this;
}

void Cow::ShowCow() const
{
	using std::cout;
	using std::endl;

	cout << endl;
	cout << "name : " << name << endl;
	cout << "hobby : " << hobby << endl;
	cout << "weight : " << weight << endl;
}
// usecow.cpp

#include <iostream>
#include "cow.h"

int main()
{
	Cow a;
	Cow b("bbb", "game", 100);
	Cow temp("aaa", "movie", 200);
	Cow c(temp);
	
	a.ShowCow();
	b.ShowCow();
	a = temp;
	a.ShowCow();
	c.ShowCow();

	return 0;
}

02

// string2.h

#ifndef STRING2_H_
#define STRING2_H_
#include <iostream>
using std::ostream;
using std::istream;

class String
{
	private:
		char * str;
		int len;
		static int num_strings;
		static const int CINLIM = 80;
	public:
		String(const char * s);
		String();
		String(const String & st);
		~String();
		int length()const { return len; };
		String & operator=(const String & st);
		String & operator=(const char * s);
		char & operator[](int i);
		const char & operator[](int i) const;
		friend bool operator<(const String & st1, const String & st2);
		friend bool operator>(const String & st1, const String & st2);
		friend bool operator==(const String & st1, const String & st2);
		friend char * operator+(const String & st1, const String & st2);
		friend ostream & operator<<(ostream & os, const String & st);
		friend istream & operator>>(istream & is, String & st);
		static int HowMany();
		void stringlow();
		void stringup();
		int has(char c);
};

#endif
// string2.cpp

#include <cstring>
#include <cctype>
#include "string2.h"
using std::cin;
using std::cout;

int String::num_strings = 0;

int String::HowMany()
{
	return num_strings;
}

void String::stringlow()
{
	for (int i = 0; str[i]; i++)
		str[i] = tolower(str[i]);
}

void String::stringup()
{
	for (int i = 0; str[i]; i++)
		str[i] = toupper(str[i]);
}

int String::has(char c)
{
	int count = 0;

	for (int i = 0; str[i]; i++)
	{
		if (str[i] == c)
			count++;
	}
	return count;
}

String::String(const char * s)
{
	len = std::strlen(s);
	str = new char[len + 1];
	std::strcpy(str, s);
	num_strings++;
}

String::String()
{
	len = 4;
	str = new char[1];
	str[0] = '\0';
	num_strings++;
}

String::String(const String & st)
{
	num_strings++;
	len = st.len;
	str = new char[len + 1];
	std::strcpy(str, st.str);
}

String::~String()
{
	--num_strings;
	delete [] str;
}

String & String::operator=(const String & st)
{
	if (this == &st)
		return *this;
	delete [] str;
	len = st.len;
	str = new char[len + 1];
	std::strcpy(str, st.str);
	return *this;
}

String & String::operator=(const char * s)
{
	delete [] str;
	len = std::strlen(s);
	str = new char[len + 1];
	std::strcpy(str, s);
	return *this;
}

char * operator+(const String & st1, const String & st2)
{
	char * str = new char[std::strlen(st1.str) + std::strlen(st2.str) + 1];
	std::strcpy(str, std::strcat(st1.str, st2.str));
	return str;
}

char & String::operator[](int i)
{
	return str[i];
}

const char & String::operator[](int i) const
{
	return str[i];
}

bool operator<(const String & st1, const String & st2)
{
	return (std::strcmp(st1.str, st2.str) < 0);
}

bool operator>(const String & st1, const String & st2)
{
	return st2 < st1;
}

bool operator==(const String & st1, const String & st2)
{
	return (std::strcmp(st1.str, st2.str) == 0);
}

ostream & operator<<(ostream & os, const String & st)
{
	os << st.str;
	return os;
}

istream & operator>>(istream & is, String & st)
{
	char temp[String::CINLIM];
	is.get(temp, String::CINLIM);
	if (is)
		st = temp;
	while (is && is.get() != '\n')
		continue;
	return is;
}
// pe12-02.cpp

#include <iostream>
using namespace std;
#include "string2.h"

int main()
{
	String s1(" and I am a C++ studnet.");
	String s2 = "영문 이름을 입력하십시오 : ";
	String s3;
	cout << s2;
	cin >> s3;
	s2 = "My name is " + s3;
	cout << s2 << ".\n";
	s2 = s2 + s1;
	s2.stringup();
	cout << "다음 문자열에는\n" << s2 << "\n문자 'A'가 "
		 << s2.has('A') << "개 들어있습니다.\n";
	s1 = "red";
	String rgb[3] = { String(s1), String("green"), String("blue") };
	cout << "빛의 삼원색의 이름을 하나만 입력하십시오 : ";
	String ans;
	bool success = false;
	while (cin >> ans)
	{
		ans.stringlow();
		for (int i = 0; i < 3; i++)
		{
			if (ans == rgb[i])
			{
				cout << "맞았습니다!\n";
				success = true;
				break;
			}
		}
		if (success)
			break;
		else
			cout << "다시 입력하십시오 : ";
	}
	cout << "프로그램을 종료합니다.\n";
	return 0;
}

03

// stock3.h

#ifndef STOCK3_H_
#define STOCK3_H_

#include <iostream>

class Stock
{
	private :
		char * company;
		int shares;
		double share_val;
		double total_val;
		void set_tot() { total_val = shares * share_val; }

	public:
		Stock();
		Stock(const char * co, long n = 0, double pr = 0.0);
		~Stock();
		void buy(long num, double price);
		void sell(long num, double price);
		void update(double price);
		friend std::ostream & operator<<(std::ostream & os, const Stock & st);
		const Stock & topval(const Stock & s) const;
};

#endif
// stock3.cpp

#include <iostream>
#include "STOCK3.h"

Stock::Stock()
{
	company = new char[8];
	strcpy(company, "no name");
	shares = 0;
	share_val = 0.0;
	total_val = 0.0;
}

Stock::Stock(const char * co, long n, double pr)
{
	company = new char[strlen(co) + 1];
	strcpy(company, co);

	if (n < 0)
	{
		std::cerr << "주식 수는 음수가 될 수 없으므로, "
				  << company << " shares를 0으로 설정합니다.\n";
		shares = 0;
	}
	else
		shares = n;
	share_val = pr;
	set_tot();
}

Stock::~Stock()
{
	delete [] company;
}

void Stock::buy(long num, double price)
{
	if (num < 0)
	{
		std::cout << "매입 주식 수는 음수가 될 수 없으므로, "
				  << "거래가 취소되었습니다.\n";
	}
	else
	{
		shares += num;
		share_val = price;
		set_tot();
	}
}

void Stock::sell(long num, double price)
{
	using std::cout;
	if (num < 0)
	{
		cout << "매입 주식 수는 음수가 될 수 없으므로, "
			 << "거래가 취소되었습니다.\n";
	}
	else if (num > shares)
	{
		cout << "보유 주식보다 많은 주식을 매도할 수 없으므로, "
			 << "거래가 취소되었습니다.\n";
	}
	else
	{
		shares -= num;
		share_val = price;
		set_tot();
	}
}

void Stock::update(double price)
{
	share_val = price;
	set_tot();
}

std::ostream & operator<<(std::ostream & os, const Stock & st)
{
	using std::ios_base;
	using std::endl;

	ios_base::fmtflags orig =
		os.setf(ios_base::fixed, ios_base::floatfield);
	std::streamsize prec = os.precision(3);

	os << "회사명 : " << st.company << endl
			  << " 주식 수 : " << st.shares << endl
			  << " 주가 : $" << st.share_val << endl;
	os.precision(2);
	os << " 주식 총 가치 : $" << st.total_val << '\n';

	os.setf(orig, ios_base::floatfield);
	os.precision(prec);
	return os;
}

const Stock & Stock::topval(const Stock & s) const
{
	if (s.total_val > total_val)
		return s;
	else
		return *this;
}
// usestock3.cpp

#include <iostream>
#include "STOCK3.h"

const int STKS = 4;

int main()
{
	Stock stocks[STKS] = {
		Stock("NanoSmart", 12, 20.0),
		Stock("Boffo Objects", 200, 2.0),
		Stock("Monolithic Obelisks", 130, 3.25),
		Stock("Fleep Enterprises", 60, 6.5)
	};

	std::cout << "보유 주식 리스트 : \n";
	int st;
	for (st = 0; st < STKS; st++)
		std::cout << stocks[st];
	const Stock * top = &stocks[0];
	for (st = 1; st< STKS; st++)
		top = &top->topval(stocks[st]);
	
	std::cout << "\n최고 가치의 주식 : \n";
	std::cout << *top;
	return 0;
}

04

// stack1.h

#ifndef STACK1_H_
#define STACK1_H_

typedef unsigned long Item;

class Stack
{
	private:
		enum {MAX = 10};
		Item * pitems;
		int size;
		int top;
	public:
		Stack(int n = MAX);
		Stack(const Stack & st);
		~Stack();
		bool isempty() const;
		bool isfull() const;
		bool push(const Item & item);
		bool pop(Item & item);
		Stack & operator=(const Stack & st);
};
// stack1.cpp

#include "stack1.h"

Stack::Stack(int n)
{
	size = n;
	pitems = new Item[size];
	top = 0;
}

Stack::Stack(const Stack & st)
{
	size = st.size;
	pitems = new Item[size];
	top = 0;
	for (int i = 0; i < st.top; i++)
		this->push(st.pitems[i]);
}

Stack::~Stack()
{
	delete [] pitems;
}

bool Stack::isempty() const
{
	return top == 0;
}

bool Stack::isfull() const
{
	return top == size;
}

bool Stack::push(const Item & item)
{
	if (top < size)
	{
		pitems[top++] = item;
		return true;
	}
	else
		return false;
}

bool Stack::pop(Item & item)
{
	if (top > 0)
	{
		item = pitems[--top];
		return true;
	}
	else
		return false;
}

Stack & Stack::operator=(const Stack & st)
{
	if (this == &st)
		return *this;
	delete [] pitems;
	size = st.size;
	pitems = new Item[size];
	top = 0;
	for (int i = 0; i < st.top; i++)
		this->push(st.pitems[i]);
	return *this;
}
// usestack1.cpp

#include <iostream>
#include <cctype>
#include "stack1.h"

int main()
{
	using namespace std;
	Stack st;
	char ch;
	unsigned long po;

	cout << "주문서를 추가하려면 A, 주문서를 처리하려면 P, \n"
		 << "종료하려면 Q를 입력하십시오.\n";
	while (cin >> ch && toupper(ch) != 'Q')
	{
		while (cin.get() != '\n')
			continue;
		if (!isalpha(ch))
		{
			cout << '\a';
			continue;
		}
		switch (ch)
		{
			case 'A':
			case 'a': cout << "추가할 주문서의 번호를 입력하십시오 : ";
					  cin >> po;
					  if (st.isfull())
					  	cout << "스택이 가득 차 있습니다.\n";
					  else
					  	st.push(po);
					  break;
			case 'P':
			case 'p': if (st.isempty())
					  	cout << "스택이 비어있습니다.\n";
					  else {
						st.pop(po);
						cout << "#" << po << " 주문서를 처리했습니다.\n";
					  }
					  break;
		}
		cout << "주문서를 추가하려면 A, 주문서를 처리하려면 P,\n"
			 << "종료하려면 Q를 입력하십시오.\n";
	}

	cout << "주문서 복사\n";
	Stack copy_stack(st);
	while (copy_stack.pop(po))
		cout << "#" << po << " 주문서를 처리했습니다.\n";

	cout << "주문서 대입\n";
	Stack new_stack;
	new_stack = st;
	while (new_stack.pop(po))
		cout << "#" << po << " 주문서를 처리했습니다.\n";

	cout << "프로그램을 종료합니다.\n";
	return 0;
}

05

// bank2.cpp

#include <iostream>
#include <cstdlib>
#include <ctime>
#include "queue.h"
const int MIN_PER_HR = 60;

bool newcustomer(double x);

int main()
{
	using std::cin;
	using std::cout;
	using std::endl;
	using std::ios_base;
	std::srand(std::time(0));

	cout << "사례 연구 : 히서 은행의 ATM\n";
	cout << "시뮬레이션 시간 수를 입력하십시오 : ";
	int hours;
	cin >> hours;
	double perhour = 60;
	
	Item temp;
	double min_per_cust;
	long turnaways;
	long customers;
	long served;
	long sum_line;
	int wait_time;
	long line_wait;

	do
	{
		Queue line(hours * perhour / 2);

		perhour--;
		min_per_cust = MIN_PER_HR / perhour;

		turnaways = 0;
		customers = 0;
		served = 0;
		sum_line = 0;
		wait_time = 0;
		line_wait = 0;
		
		for (int cycle = 0; cycle < perhour; cycle++)
		{
			if (newcustomer(min_per_cust))
			{

				if (line.isfull())
					turnaways++;
				else
				{
					customers++;
					temp.set(cycle);
					line.enqueue(temp);
				}
			}
			if (wait_time <= 0 && !line.isempty())
			{
				line.dequeue(temp);
				wait_time = temp.ptime();
				line_wait += cycle - temp.when();
				served++;
			}
			if (wait_time > 0)
				wait_time--;
			sum_line += line.queuecount();
		}
	} while (double(line_wait) / (served) > 1.0);

	if (customers > 0)
	{
		cout << " 큐에 줄을 선 고객 수 : " << customers << endl;
		cout << "거래를 처리한 고객 수 : " << served << endl;
		cout << " 발길을 돌린 고객 수 : " << turnaways << endl;
		cout << "	평균 큐의 길이 : ";
		cout.precision(2);
		cout.setf(ios_base::fixed, ios_base::floatfield);
		cout.setf(ios_base::showpoint);
		cout << (double) (sum_line) / perhour << endl;
		cout << "시간당 평균 고객수가 "<< perhour << "명 일때의 평균 대기 시간 : "
			 << (double) (line_wait) / (served) << "분\n";
	}
	else
		cout << "고객이 한 명도 없습니다!\n";
	
	
	cout << "완료!\n";
	return 0;
}

bool newcustomer(double x)
{
	return (std::rand() * x / RAND_MAX < 1);
}

06

// bank3.cpp

#include <iostream>
#include <cstdlib>
#include <ctime>
#include "queue.h"
const int MIN_PER_HR = 60;

bool newcustomer(double x);

int main()
{
	using std::cin;
	using std::cout;
	using std::endl;
	using std::ios_base;
	std::srand(std::time(0));

	cout << "사례 연구 : 히서 은행의 ATM\n";
	cout << "시뮬레이션 시간 수를 입력하십시오 : ";
	int hours;
	cin >> hours;
	double perhour = 120;
	
	Item temp;
	double min_per_cust;
	long turnaways, turnaways2;
	long customers, customers2;
	long served, served2;
	long sum_line, sum_line2;
	int wait_time, wait_time2;
	long line_wait, line_wait2;

	do
	{
		Queue line(hours * perhour / 2);
		Queue line2(hours * perhour / 2);

		perhour--;
		min_per_cust = MIN_PER_HR / perhour;

		turnaways = turnaways2 = 0;
		customers = customers2 = 0;
		served = served2 = 0;
		sum_line = sum_line2 = 0;
		wait_time = wait_time2 = 0;
		line_wait = line_wait2 = 0;
		
		for (int cycle = 0; cycle < perhour; cycle++)
		{
			if (newcustomer(min_per_cust))
			{
				if (line.queuecount() <= line2.queuecount())
				{
					if (line.isfull())
						turnaways++;
					else
					{
						customers++;
						temp.set(cycle);
						line.enqueue(temp);
					}
				}
				else
				{
					if (line2.isfull())
						turnaways2++;
					else
					{
						customers2++;
						temp.set(cycle);
						line2.enqueue(temp);
					}
				}
			}
			if (wait_time <= 0 && !line.isempty())
			{
				line.dequeue(temp);
				wait_time = temp.ptime();
				line_wait += cycle - temp.when();
				served++;
			}
			if (wait_time2 <= 0 && !line2.isempty())
			{
				line2.dequeue(temp);
				wait_time2 = temp.ptime();
				line_wait2 += cycle - temp.when();
				served2++;
			}
			if (wait_time > 0)
				wait_time--;
			if (wait_time2 > 0)
				wait_time2--;
			sum_line += line.queuecount();
			sum_line2 += line2.queuecount();
		}
	} while (double(line_wait + line_wait2) / (served + served2) > 1.0);
	
	if (customers + customers2 > 0)
	{
		cout << " 큐에 줄을 선 고객 수 : " << customers + customers2 << endl;
		cout << "거래를 처리한 고객 수 : " << served + served2 << endl;
		cout << " 발길을 돌린 고객 수 : " << turnaways + turnaways2 << endl;
		cout << "	평균 큐의 길이 : ";
		cout.precision(2);
		cout.setf(ios_base::fixed, ios_base::floatfield);
		cout.setf(ios_base::showpoint);
		cout << (double) (sum_line + sum_line2) / perhour << endl;
		cout << "시간당 평균 고객수가 "<< perhour << "명 일때의 평균 대기 시간 : "
			 << (double) (line_wait + line_wait2) / (served + served2) << "분\n";
	}
	else
		cout << "고객이 한 명도 없습니다!\n";
	
	
	cout << "완료!\n";
	return 0;
}

bool newcustomer(double x)
{
	return (std::rand() * x / RAND_MAX < 1);
}

'개인공부 > C++ 기초플러스' 카테고리의 다른 글

C++ Primer 13 Exercise  (0) 2023.02.19
C++ Primer 13  (0) 2023.02.19
C++ Primer 12  (0) 2023.02.19
C++ Primer 11 Exercise  (0) 2023.02.19
C++ Primer 11  (0) 2023.02.19

댓글