C++ Primer 12 프로그래밍 연습
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);
};
#endif
// 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);
}