您的位置:首页 > 编程语言

(一三五)第十二章编程练习

2016-01-30 01:56 302 查看
1.对于下面的类声明

class Cow{

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; //display all cow data

};

给这个类提供实现,并编写一个使用所有成员函数的小程序。

答:

#include<iostream>

class Cow
{
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;	//display all cow data
};

int main()
{
using namespace std;
{
Cow one;	//默认
Cow two("小强", "桌球", 140);	//构造
Cow three(two);	//复制
Cow four("小李", "跑步", 160);
two.ShowCow();	//显示
four.ShowCow();
one = four = two;	//赋值
one.ShowCow();
four.ShowCow();
}	//由于离开代码块会自动调用析构函数,因此这里不应该调用任何一个对象的析构函数
system("pause");
return 0;
}

Cow::Cow()	//默认构造函数
{
name[0] = '\0';	//空字符
hobby = nullptr;	//空指针
weight = 0;		//0
}
Cow::Cow(const char*nm, const char * ho, double wt)	//构造函数
{
strcpy_s(name, strlen(nm) + 1, nm);	//这个没有考虑到若nm超出19个字符(不包含空字符)将怎么办
hobby = new char[strlen(ho) + 1];
strcpy_s(hobby, strlen(ho) + 1, ho);
weight = wt;
}
Cow::Cow(const Cow &c)	//复制构造函数
{
strcpy_s(name, strlen(c.name) + 1, c.name);
hobby = new char[strlen(c.hobby) + 1];
strcpy_s(name, strlen(c.hobby) + 1, c.hobby);
weight = weight;
}
Cow::~Cow()	//析构函数
{
std::cout << name << " is over." << std::endl;
delete[]hobby;
}
Cow & Cow::operator=(const Cow &c)	//赋值运算符重载
{
if (this == &c)return *this;
strcpy_s(name, strlen(c.name) + 1, c.name);
delete[]hobby;
hobby = new char[strlen(c.hobby) + 1];
strcpy_s(hobby, strlen(c.hobby) + 1, c.hobby);
weight = c.weight;
return *this;
}
void Cow::ShowCow() const	//display all cow data
{
std::cout << "Name: " << name << ", Hobby: " << hobby << ", Weight: " << weight << std::endl;
}


显示:

Name: 小强, Hobby: 桌球, Weight: 140
Name: 小李, Hobby: 跑步, Weight: 160
Name: 小强, Hobby: 桌球, Weight: 140
Name: 小强, Hobby: 桌球, Weight: 140
小强 is over.
桌球 is over.
小强 is over.
小强 is over.
请按任意键继续. . .


2.通过完成下面的工作来改进String类声明(即将String1.h升级为String2.h)。

a。对+运算符进行重载,使之可将两个字符串合并成1个。

b。提供一个Stringlow()成员函数,将字符串中所有的字母字符转换为小写(别忘了cctype系列字符函数)。

c。提供String()成员函数,将字符串中所有字母字符转换成大写。

d。提供一个这样的成员函数,它接受一个char参数,返回该字符在字符串中出现的字数。

使用下面的程序来测试您的工作:

//pe12_2.cpp

#include<iostream>

using namespace std;

#include"string2.h"

int main()

{

String s1(" and I am a C++ student.");

String s2 = "Please enter your name: ";

String s3;

cout << s2; //overload <<operator

cin >> s3; //overload >>operator

s2 = "My name is " + s3; //overload = , + operators

cout << s2 << ".\n";

s2 = s2 + s1;

s2.stringup(); //converts string to uppercase

cout << "The string\n" << s2 << "\ncontains " << s2.has('A') << " 'A' characters in it.\n";

s1 = "red"; //String (const char *),

//then String & operator= (const String&)

String rgb[3] = { String(s1), String("green"), String("blue")};

cout << "Enter the name of a primary color for mixing light: ";

String ans;

bool success = false;

while (cin >> ans)

{

ans.stringlow(); //converts string to lowercase

for (int i = 0; i < 3; i++)

{

if (ans == rgb[i]) //overload == operator

{

cout << "That's right!\n";

success = true;

break;

}

}

if (success)

break;

else

cout << "Try again!\n";

}

cout << "Bye\n";

return ;

}

输出应与下面相似:

Please enter your name: Fretts Farbo

My name is Fretta Farbo.

The strign

MY NAME ISFRETTA FARBO AND I AM A C++ STUDENT.

contains 6 'A' characters in it.

Enter the name of a primary color for mixing light: yellow

Try again!

BLUE

Tha's right!

Bye

答:

//string2.h	类定义
#pragma once
#ifndef STRING2_H_
#define STRING2_H_
#include<iostream>
using std::ostream;
using std::istream;

class String
{
private:
char * std;
int len;
public:
String(const char * s);
String();
String(const String &);	//复制构造函数
~String();
int length()const { return len; }	//返回字符串长度
String & operator=(const String &);
String & operator=(const char*);
int has(char m);	//返回对象中,参数的字符的个数
void stringup();	//把小写变为大写字母
void stringlow();	//把大写变小写字母
String operator+(const String&m);	//对象+对象
friend String operator+(const char* n, const String&m);	//字符串+String类
friend bool operator==(const String &st, const String &st2);	//运算符重载==
friend ostream & operator<<(ostream & os, const String &st);//<<重载
friend istream & operator>>(istream & is, String &st);	//>>重载
};
#endif

//string2.cpp 用于存放String类的方法
#include<iostream>
#include"string2.h"

String::String(const char * s)	//构造函数,用于将字符串作为参数
{
len = strlen(s);
std = new char[len + 1];
strcpy_s(std, len + 1, s);
}
String::String()	//默认构造函数
{
len = 6;
std = new char[len + 1];
strcpy_s(std, len + 1, "未命名");
}
String::String(const String & m)	//复制构造函数,新建一个对象,并将其初始化为同类现有对象时调用,需要增加计数器
{
len = m.len;
std = new char[len + 1];
strcpy_s(std, len + 1, m.std);
}
String::~String()	//析构函数,需要delete对象new出来的动态内存
{
delete[]std;
}
String & String::operator=(const String & m)	//赋值运算符重载,无需增加计数器
{
if (this == &m)return *this;	//防止将自己赋值给自己
delete[]std;	//因为是已存在对象,然后下面要new,所以这里需要先delete
len = m.len;
std = new char[len + 1];
strcpy_s(std, len + 1, m.std);
return *this;
}
String & String::operator=(const char*m)	//赋值运算符重载,用于将字符串赋给类对象时调用,不增加计数器,因为这个用来避免创造临时对象
{
delete[]std;	//已存在对象,下面要new,因此delete
len = strlen(m);
std = new char[len + 1];
strcpy_s(std, len + 1, m);
return *this;
}
int String::has(char m)	//返回对象中,参数的字符的个数
{
int j = 0;
for (int i = 0;std[i] != '\0';i++)
{
if (std[i] == m)j++;
}
return j;
}

String String::operator+(const String&m)	//对象+对象
{
String a;
a.len = len + m.len;
delete[]a.std;
a.std = new char[a.len + 1];
strcpy_s(a.std, len + 1, std);
strcpy_s(a.std + len, m.len + 1, m.std);	//连续复制
return a;
}

bool operator==(const String &st, const String &st2)
{
return (strcmp(st.std, st2.std) == 0);
}
void String::stringup()	//把小写变为大写字母
{
for (int i = 0;std[i] != '\0';i++)
std[i]=toupper(std[i]);		//如果不是小写字母,返回自己,如果是小写字母,返回大写字母(于是被替换了)
}
void String::stringlow()	//把大写变小写字母
{
for (int i = 0;std[i] != '\0';i++)
std[i]=tolower(std[i]);		//同上面那个
}
String operator+(const char* n, const String&m)	//字符串+String类
{
String a;
a.len = strlen(n) + strlen(m.std);
a.std = new char[a.len + 1];
strcpy_s(a.std, strlen(n) + 1, n);
strcpy_s(a.std + strlen(n), strlen(m.std) + 1, m.std);	//连续复制
return a;
}

ostream & operator<<(ostream & os, const String &st)	//输出运算符重载
{
os << st.std;
return os;
}
istream & operator>>(istream & is, String &st)	//输入运算符重载
{
delete[]st.std;
char *q = new char[100];	//用一个间接的储存输入的内容
is.get(q, 100);
while (is.get() != '\n')is.get();	//由于要求清除换行符,所以不能直接用is>>q这种形式,需要读取掉换行符。
st.len = strlen(q);
st.std = new char[st.len + 1];
strcpy_s(st.std, st.len + 1, q);	//然后复制进去
delete[]q;	//删除这个间接的
return is;
}

//1.cpp main函数,用于测试
#include<iostream>
using namespace std;
#include"string2.h"

int main()
{
String s1(" and I am a C++ student.");
String s2 = "Please enter your name: ";
String s3;
cout << s2;	//overload <<operator
cin >> s3;	//overload >>operator
s2 = "My name is " + s3;	//overload = , + operators
cout << s2 << ".\n";
s2 = s2 + s1;
s2.stringup();		//converts string to uppercase
cout << "The string\n" << s2 << "\ncontains " << s2.has('A') << " 'A' characters in it.\n";
s1 = "red";		//String (const char *),
//then String & operator= (const String&)
String rgb[3] = { String(s1), String("green"), String("blue") };
cout << "Enter the name of a primary color for mixing light: ";
String ans;
bool success = false;
while (cin >> ans)
{
ans.stringlow();		//converts string to lowercase
for (int i = 0; i < 3; i++)
{
if (ans == rgb[i])	//overload == operator
{
cout << "That's right!\n";
success = true;
break;
}
}
if (success)
break;
else
cout << "Try again!\n";
}
cout << "Bye\n";
system("pause");
return 0;
}


显示:

Please enter your name: Fretta Farbo
My name is Fretta Farbo.
The string
MY NAME IS FRETTA FARBO AND I AM A C++ STUDENT.
contains 6 'A' characters in it.
Enter the name of a primary color for mixing light: yellow
Try again!
BLUE
That's right!
Bye
请按任意键继续. . .


3.新编写程序清单10.7和程序清单10.8描述的Stock类,使之使用动态分配的内存,而不是string类对象来存储股票名称。另外,使用重载的perator<<()定义代替show()成员函数。再使用程序清单10.9测试新的定义程序。

答:

//stock.h	Stock类定义
#ifndef STOCK_H_
#define STOCK_H_
#include<ostream>

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(const Stock&n);	//复制构造函数
~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& m);
const Stock & topval(const Stock & s) const;
};

#endif // !STOCK_H_

//stock.cpp
#include<iostream>
#include"stock.h"
char* company;	//股票名字
int shares;	//股票的数量
double share_val;	//平均每股价格
double total_val;	//总共的价值
void set_tot() { total_val = shares * share_val; }

Stock::Stock()
{
company = nullptr;
shares = share_val = total_val = 0;
}
Stock::Stock(const char* co, long n, double pr)
{
company = new char[strlen(co) + 1];
strcpy_s(company, strlen(co) + 1, co);	//复制进去
shares = n;
share_val = pr;
set_tot();
}
Stock::~Stock()
{
delete[]company;
}
Stock::Stock(const Stock&n)
{
delete[]company;
company = new char[strlen(n.company) + 1];
strcpy_s(company, strlen(n.company) + 1, n.company);
shares = n.shares;
share_val = n.share_val;
set_tot();
}
void Stock::buy(long num, double price)	//股票数量以及买入时每股价格(此时算的是股票的总价值,不是自己花费的总金钱)
{
shares += num;	//数量相加
share_val = price;
set_tot();
}
void Stock::sell(long num, double price)
{
if (num > shares)
{
std::cout << "卖出失败" << std::endl;
return;
}
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& m)
{
os << "股票名字:" << m.company << ",持股数量:" << m.shares << ",每股均价:" << m.share_val << ",总价值:" << m.total_val;
return os;
}
const Stock & Stock::topval(const Stock & s) const
{
if (total_val >= s.total_val)return *this;
else return s;
}

//1.cpp main函数,测试
#include<iostream>
#include"stock.h"

const int STKS = 4;

int main()
{
using std::cout;
using std::endl;
Stock stocks[STKS] =	//构造函数
{
Stock("NanoSmart",12,20.0),
Stock("Boff Objects",200,2.0),
Stock("Monolithic Obelisks",130,3.25),
Stock("Fleep Enterpriss",60,6.5)
};

std::cout << "Stock holdings:\n";
int st;
for (st = 0;st < STKS;st++)
cout << stocks[st] << endl;

const Stock*top = &stocks[0];
for (st = 1;st < STKS;st++)
top = &top->topval(stocks[st]);
std::cout << "\nMost valuable holding:\n";
cout << *top << endl;
system("pause");
return 0;
}


显示:

Stock holdings:
股票名字:NanoSmart,持股数量:12,每股均价:20,总价值:240
股票名字:Boff Objects,持股数量:200,每股均价:2,总价值:400
股票名字:Monolithic Obelisks,持股数量:130,每股均价:3.25,总价值:422.5
股票名字:Fleep Enterpriss,持股数量:60,每股均价:6.5,总价值:390

Most valuable holding:
股票名字:Monolithic Obelisks,持股数量:130,每股均价:3.25,总价值:422.5
请按任意键继续. . .


4.请看下面程序清单10.10定义的Stack类的变量:

//stack.h -- class declaration for the stack ADT

typedef unsigned long Item;

class Stack

{

private:

enum {MAX = 10}; //constant specific to class

Item * pitems; //holds stack items

int size; // number of elements in stack

int top; // index for top stack item

public:

Stack(int n = MAX); //creates stack with n elements

Stack(const Stack & st);

~Stack();

bool isempty() const;

bool isfull() const;

//push() returns false if stack already is full, true otherwise

bool push(const Item & item); // add item to stack

// pop() returns false ifstack already is empty ,true otherwise

bool pop (Item & item); // pop top into item

Stack & operator=(const Stack & st);

};

正如私有成员表明的,这个类使用动态分配的数组来保存栈项。请重新编写方法,以适应这种新的表示法,并编写一个程序来演示所有的方法,包括复制构造函数和赋值运算符。

答:

//stack.h -- class declaration for the stack ADT
#ifndef STACK_H_
#define STACK_H_
typedef unsigned long Item;

class Stack
{
private:
enum { MAX = 10 };	//类具体的常量
Item * pitems;		//拥有堆的空间(意思就是这个用堆的内存,要new)
int size;				//number of elements in stack,堆中的元素数(即最大多少个)
int top;				//堆最高的位置(也就是下一个进入使用的位置)
public:
Stack(int n = MAX);	//创造一个使用n个元素的堆
Stack(const Stack & st);	//复制构造函数
~Stack();	//析构
bool isempty() const;	//是否空
bool isfull() const;	//是否满

//push() 如果满,返回false,否则true
bool push(const Item & item);		// add item to stack
// pop() 如果空,返回false,否则true
bool pop(Item & item);		// pop top into item
Stack & operator=(const Stack & st);	//赋值运算符重载
};

#endif // !STACK_H_

//stack.cpp	 源代码文件
#include<iostream>
#include"stack.h"

enum { MAX = 10 };	//类具体的常量
Item * pitems;		//拥有堆的空间(意思就是这个用堆的内存,要new)
int size;				//number of elements in stack,堆中的元素数(即最大多少个)
int top;				//堆最高的位置(也就是下一个进入使用的位置)

Stack::Stack(int n)	//创造一个使用n个元素的堆
{
pitems = new Item
;
size = n;
top = 0;
}
Stack::Stack(const Stack & st)	//复制构造函数
{
size = st.size;
pitems = new Item[size];
for (top = 0;top < st.top;top++)
pitems[top] = st.pitems[top];	//逐成员复制
}
Stack::~Stack()	//析构
{
delete[]pitems;
}
bool Stack::isempty() const	//是否空
{
return (top == 0);
}
bool Stack::isfull() const	//是否满
{
return (top == size);
}

//push() 如果满,返回false,否则true
bool Stack::push(const Item & item)		// add item to stack
{
if (isfull())return false;
pitems[top++] = item;	//赋值给当前进入的地方,然后top+1
return true;
}

// pop() 如果空,返回false,否则true
bool Stack::pop(Item & item)		// pop top into item
{
if (isempty())return false;
item = pitems[--top];	//取出,top-1后将其赋值给参数
return true;
}

Stack & Stack::operator=(const Stack & st)	//赋值运算符重载
{
if (this == &st)return *this;
delete[]pitems;
size = st.size;
pitems = new Item[size];
for (top = 0;top < st.top;top++)
pitems[top] = st.pitems[top];	//逐成员复制
return *this;
}

//1.cpp main函数,测试
#include<iostream>
#include"stack.h"

int main()
{
using namespace std;
Stack one(5);
Item num;
for (int i = 0;i < 6;i++)
{
cout << "输入一个数字,将被放入到Stack one中:";
cin >> num;
if (one.push(num))cout << "成功放入!" << endl;
else cout << "放入失败!" << endl;
}
cout << endl << endl;
cout << "Stack two被创建,one被复制给她" << endl;
Stack two = one;
Stack three;
cin.sync();
for (int i = 0;i < 6;i++)
{
cout << "按一下,将从Stack one取出你放入数字";
cin.get();
if (one.pop(num))cout << "成功取出,数字是" << num << endl;
else cout << "空了,取出失败!" << endl;
if (i == 2)
{
cout << "one被复制到three之中" << endl;
three = one;
}
}
cout << endl << endl;
for (int i = 0;i < 6;i++)
{
cout << "按一下,将从Stack two取出你放入数字";
cin.get();
if (two.pop(num))cout << "成功取出,数字是" << num << endl;
else cout << "空了,取出失败!" << endl;
}
cout << endl << endl;
for (int i = 0;i < 6;i++)
{
cout << "按一下,将从Stack three取出你放入数字";
cin.get();
if (three.pop(num))cout << "成功取出,数字是" << num << endl;
else
{
cout << "空了,取出失败!" << endl;
i = 6;
}
}
system("pause");
return 0;
}


显示:

输入一个数字,将被放入到Stack one中:1
成功放入!
输入一个数字,将被放入到Stack one中:2
成功放入!
输入一个数字,将被放入到Stack one中:3
成功放入!
输入一个数字,将被放入到Stack one中:4
成功放入!
输入一个数字,将被放入到Stack one中:5
成功放入!
输入一个数字,将被放入到Stack one中:6
放入失败!

Stack two被创建,one被复制给她
按一下,将从Stack one取出你放入数字
成功取出,数字是5
按一下,将从Stack one取出你放入数字
成功取出,数字是4
按一下,将从Stack one取出你放入数字
成功取出,数字是3
one被复制到three之中
按一下,将从Stack one取出你放入数字
成功取出,数字是2
按一下,将从Stack one取出你放入数字
成功取出,数字是1
按一下,将从Stack one取出你放入数字
空了,取出失败!

按一下,将从Stack two取出你放入数字
成功取出,数字是5
按一下,将从Stack two取出你放入数字
成功取出,数字是4
按一下,将从Stack two取出你放入数字
成功取出,数字是3
按一下,将从Stack two取出你放入数字
成功取出,数字是2
按一下,将从Stack two取出你放入数字
成功取出,数字是1
按一下,将从Stack two取出你放入数字
空了,取出失败!

按一下,将从Stack three取出你放入数字
成功取出,数字是2
按一下,将从Stack three取出你放入数字
成功取出,数字是1
按一下,将从Stack three取出你放入数字
空了,取出失败!
请按任意键继续. . .


5.Heather银行进行的研究表明,ATM客户不希望排队时间超过1分钟。使用程序清单12.10中的模拟,找出要使平均等候时间为1分钟,每小时到达的客户数应为多少(试验时间不短于100小时)?

答:

经过模拟,大概在每分钟18人的时候,平均等候时间约1分钟稍微多一点点,17人的时候少于1分钟。

然后上书上代码:

//queue.h
#ifndef QUEUE_H_
#define QEUEU_H_

class Customer
{
private:
long arrive;
int processtime;
public:
Customer() { arrive = processtime = 0; }
void set(long when);
long when()const { return arrive; }
int ptime()const { return processtime; }
};

typedef Customer Item;

class Queue
{
private:
struct Node { Item item;struct Node*next; };
enum { Q_SIZE = 10 };
Node*rear;
Node*front;
int items;
const int qsize;
Queue(const Queue&q):qsize(0){}
Queue&operator=(const Queue&q) { return *this; }
public:
Queue(int qs = Q_SIZE);
~Queue();
bool isempty()const;
bool isfull()const;
int queuecout()const;
bool enqueue(const Item&item);
bool dequeue(Item&item);
};

#endif

//queue.cpp
#include"queue.h"
#include<cstdlib>

Queue::Queue(int qs) :qsize(qs)
{
front = rear = NULL;
items = 0;
}
Queue::~Queue()
{
Node*temp;
while (front != nullptr)
{
temp = front;
front = front->next;
delete temp;
}
}
bool Queue::isempty()const
{
return items == 0;
}
bool Queue::isfull()const
{
return items == qsize;
}
int Queue::queuecout()const
{
return items;
}
bool Queue::enqueue(const Item&item)
{
if (isfull())
return false;
Node*add = new Node;
add->item = item;
add->next = NULL;
items++;
if (front == NULL)
front = add;
else
rear->next = add;
rear = add;
return true;
}
bool Queue::dequeue(Item&item)
{
if (front == NULL)
return false;
item = front->item;
items--;
Node*temp = front;
front = front->next;
delete temp;
if (items == 0)
rear = nullptr;
return true;
}
void Customer::set(long when)
{
processtime = std::rand() % 3 + 1;
arrive = when;
}

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

bool newcustomer(double x);

int main()
{
using namespace std;
srand(time(0));

cout << "Case Study: Bank of Heather Automatic Teller\n";
cout << "Enter maximum size of queue: ";
int qs;
cin >> qs;
Queue line(qs);

cout << "Enter the number of simulation hours: ";
int hours;
cin >> hours;
long cyclelimit = MIN_PER_HR*hours;
cout << "Enter the average number of customer per hour: ";
double perhour;
cin >> perhour;
double min_per_cust;
min_per_cust = MIN_PER_HR / perhour;

Item temp;
long turnaways = 0;
long customers = 0;
long served = 0;
long sum_line = 0;
int wait_time = 0;
long line_wait = 0;

for (int cycle = 0;cycle < cyclelimit;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.queuecout();
}
if (customers > 0)
{
cout << "customers accepted: " << customers << endl;
cout << "  customers served: " << served << endl;
cout << "         turnaways: " << turnaways << endl;
cout << "average queue size: ";
cout.precision(2);
cout.setf(ios_base::fixed, ios_base::floatfield);
cout << (double)sum_line / cyclelimit << endl;
cout << " average wait time: " << (double)line_wait / served << " minutes\n";
}
else
cout << "No customers!\n";
cout << "Done!\n";
system("pause");
return 0;
}

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


6.Heather银行想知道,如果再开设一台ATM,情况将如何。请对模拟进行修改,以包含两个队列。假设当第一台ATM前的排队人数少于第二台ATM时,客户将排在第一队,否则将排在第二队。然后再找出要使平均等候时间为1分钟,每小时到达的客户数应该为多少(注意,这是一个非线性问题,即将ATM数量加倍,并不能保证每小时处理的客户数量也翻倍,并确保客户等候的时间少于1分钟)?

答:

约50个人的时候,平均等待时间少于1分钟。

模拟结果:

Two ATMs

Case Study: Bank of Heather Automatic Teller

Enter maximum size of queue: 10

Enter the number of simulation hours: 10000

Enter the average number of customer per hour: 50

customers accepted: 499929

customers served: 499928

turnaways: 0

average queue size: 0.40

average wait time: 0.96 minutes

Done!

请按任意键继续. . .

仅改动main函数

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

bool newcustomer(double x);

int main()
{
using namespace std;
srand(time(0));
cout << "Two ATMs" << endl;
cout << "Case Study: Bank of Heather Automatic Teller\n";
cout << "Enter maximum size of queue: ";
int qs;
cin >> qs;
Queue line(qs);
Queue line2(qs);	//第二台ATM

cout << "Enter the number of simulation hours: ";
int hours;
cin >> hours;
long cyclelimit = MIN_PER_HR*hours;
cout << "Enter the average number of customer per hour: ";
double perhour;
cin >> perhour;
double min_per_cust;
min_per_cust = MIN_PER_HR / perhour;

Item temp;	//临时对象,1#正在办理的
long turnaways = 0;	//离开的顾客
long customers = 0;	//进入排队的顾客数
long served = 0;	//服务的顾客数
long sum_line = 0;	//ATM的排队总长度
int wait_time = 0;	//等待时间
int wait_time2 = 0;	//2#ATM的等待时间
long line_wait = 0;	//队伍等待时间

for (int cycle = 0;cycle < cyclelimit;cycle++)
{
if (newcustomer(min_per_cust))	//有新顾客来了
{
if (line.isfull()&&line2.isfull())	//都满了,才走
turnaways++;
else
{
customers++;
temp.set(cycle);
if (line2.queuecout() > line.queuecout())	//2#ATM比1#ATM排队的人数多
line.enqueue(temp);//进入1#ATM
else line2.enqueue(temp);	//进入2#ATM

}
}
if (wait_time <= 0 && !line.isempty())	//如果1#ATM的等待时间小于0,且队伍里有人,队伍最前面的人开始办理(服务的顾客数+1)
{
line.dequeue(temp);
wait_time = temp.ptime();
line_wait += cycle - temp.when();
served++;
}
if (wait_time2 <= 0 && !line2.isempty())	//如果2#ATM的等待时间小于0,且队伍里有人,队伍最前面的人开始办理
{
line2.dequeue(temp);
wait_time2 = temp.ptime();
line_wait += cycle - temp.when();
served++;
}

if (wait_time > 0)
wait_time--;
if (wait_time2 > 0)
wait_time2--;
sum_line += line.queuecout()+line2.queuecout();
}
if (customers > 0)
{
cout << "customers accepted: " << customers << endl;
cout << "  customers served: " << served << endl;
cout << "         turnaways: " << turnaways << endl;
cout << "average queue size: ";
cout.precision(2);
cout.setf(ios_base::fixed, ios_base::floatfield);
cout << (double)sum_line / 2 / cyclelimit << endl;
cout << " average wait time: " << (double)line_wait / served << " minutes\n";
}
else
cout << "No customers!\n";
cout << "Done!\n";
system("pause");
return 0;
}

bool newcustomer(double x)
{
return (std::rand()*x / RAND_MAX < 1);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: