第十一章编程练习

阅读: 评论:0

第十一章编程练习

第十一章编程练习

1.修改程序清单11.15,使之将一系列连续的随机漫步者位置写入到文件中。对于每个位置,用步号进行标记。另外,让该程序将初始条件(目标距离和步长)以及结果小结写入到该文件中。该文件的内容与下面类似:
Target Distance: 100, Step size: 20
0: (x, y) = (0, 0)
1: (x, y) = (-11.4715, 16.383)
2: (x, y) = (-8.68807, -3.422232)

26: (x,y) = (42.2919, -78.2594)
27: (x,y) = (58.6749, -89.7309)
After 27 steps, the subject has the following location:
(x,y) = (58.6749, -89.7309)
or
(m,a) = (107.212, -56.8194)
Average outward distance per step = 3.97081

实现:
vect.h

#pragma once
#include <iostream>namespace VECTOR
{class Vector{public:enum Mode{RECT, POL};//RECT for rectangular, POL for polar modesprivate:double x;//horizontal valuedouble y;//vertical valuedouble mag;//length of vectordouble ang;//direction of vector in degreesMode mode;//private methods for setting valuesvoid set_mag();void set_ang();void set_x();void set_y();public:Vector();Vector(double n1, double n2, Mode form = RECT);void reset(double n1, double n2, Mode form = RECT);~Vector();double xval() const { return x; }double yval() const { return y; }double magval() const { return mag; }double angval() const { return ang; }void polar_mode();//set mode to POLvoid rect_mode();//set mode to RECT//operator overloadingVector operator+(const Vector& b) const;Vector operator-(const Vector& b)const;Vector operator-()const;Vector operator*(double n) const;//friendsfriend Vector operator* (double n, const Vector& a);friend std::ostream& operator<< (std::ostream& os, const Vector& v);};
}

vect.cpp

#include "vect.h"
using std::sqrt;
using std::sin;
using std::cos;
using std::atan;
using std::atan2;
using std::cout;namespace VECTOR
{//compute degrees in one radianconst double Rad_to_Deg = 45.0 / atan(1.0);//about 57.2957795130823//private methods, calculating magnitude from x and yvoid Vector::set_mag(){mag = sqrt(x * x + y * y);}void Vector::set_ang(){if (x == 0.0 && y == 0.0){ang = 0.0;}else{ang = atan2(y, x);}}//set x from polar coordinatevoid Vector::set_x(){x = mag * cos(ang);}//set y from polar coordinatevoid Vector::set_y(){y = mag * sin(ang);}//public methods Vector::Vector()//default constructor{x = y = mag = ang = 0.0;mode = RECT;}//constructor vector from rectangular coordinates if form is r//(the default) or else from polar coordinate if form is pVector::Vector(double n1, double n2, Mode form){mode = form;if (form == RECT){x = n1;y = n2;set_mag();set_ang();}else if(form == POL){mag = n1;ang = n2 / Rad_to_Deg;set_x();set_y();}else{cout << "Incorrect 3rd argument to Vector()--";cout << "vector set to 0n";x = y = mag = ang = 0.0;mode = RECT;}}//reset vector from rectangular coordinates if form is RECT//or else from polar coordinates if form is POLvoid Vector::reset(double n1, double n2, Mode form){mode = form;if (form == RECT){x = n1;y = n2;set_mag();set_ang();}else if (form == POL){mag = n1;ang = n2 / Rad_to_Deg;set_x();set_y();}else{cout << "Incorrect 3rd argument to Vector()--";cout << "vector set to 0n";x = y = mag = ang = 0.0;mode = RECT;}}//dectructorVector::~Vector(){}//set to polar modevoid Vector::polar_mode(){mode = POL;}//set to rectangular modevoid Vector::rect_mode(){mode = RECT;}//operator overloading//add two VectorsVector Vector::operator+(const Vector& b) const{return Vector(x + b.x, y + b.y);}//subtract Vector b from aVector Vector::operator-(const Vector& b) const{return Vector(x - b.x, y - b.y);}//reverse sign of VectorVector Vector::operator-() const{return Vector(-x, -y);}//multiply vector by nVector Vector::operator*(double n) const{return Vector(n * x, n * y);}//friend methods//multiply n by Vector aVector operator*(double n, const Vector& a){return a * n;}//display rectangular coordinates if mode is RECT, //else display polar coordinates if mode is POLstd::ostream& operator<<(std::ostream& os, const Vector& v){if (v.mode == Vector::RECT){os << "(x,y) = (" << v.x << "," << v.y << ")";}else if (v.mode == Vector::POL){os << "(m,a) = (" << v.mag << "," << v.ang * Rad_to_Deg << ")";}else{os << "Vector object mode is invalid";}return os;}
}

main.cpp

#include <iostream>#include <fstream>//ofstream
#include "vect.h"
int main(void)
{using VECTOR::Vector;using std::ofstream;double target;double dstep;srand(time(0));double direction;Vector step;Vector result(0.0, 0.0);unsigned long steps = 0;ofstream fout;fout.open(&#");//当前路径下cout << "Enter target distance(q to quit):";while (cin >> target){cout << "Enter step length:";if (!(cin >> dstep)){break;}fout << "Target Distance: " << target << ", Step Size: " << dstep;while (result.magval() < target){fout << steps << ":(x, y) = " << result << endl;direction = rand() % set(dstep, direction, Vector::POL);result = result + step;steps++;}cout << "After " << steps << " steps, the subject has the following location:n";cout << result << endl;fout << "After " << steps << " steps, the subject has the following location:n";fout << result << endl;result.polar_mode();cout << " orn" << result << endl;fout << " orn" << result << endl;cout << "Average outward distance per step = " << result.magval() / steps << endl;fout << "Average outward distance per step = " << result.magval() / steps << endl;steps = set(0.0, 0.0);cout << "Enter target distance(q to quit):";}cout << "Bye!" << endl;cin.clear();while (() != 'n'){continue;}return 0;
}

2.对Vector类的头文件(程序清单11.13)和实现文件(程序清单11.14)进行修改,使其不再存储矢量的长度和角度,而是在magval()和angval()被调用时计算它们。
应保留公有接口不变(公有方法及其参数不变),但对私有部分(包括一些私有方法)和方法实现进行修改。然后,使用程序清单11.15对修改后的版本进行测试,结果应该与以前相同,因为Vector类的公有接口与原来相同。
实现:
vect.h

namespace VECTOR
{class Vector{public:enum Mode { RECT, POL };//RECT for rectangular, POL for polar modesprivate:double x;//horizontal valuedouble y;//vertical valueMode mode;//private methods for setting valuesvoid set_x(double mag, double ang);void set_y(double mag, double ang);public:Vector();Vector(double n1, double n2, Mode form = RECT);void reset(double n1, double n2, Mode form = RECT);~Vector();double xval() const { return x; }double yval() const { return y; }double magval() const;double angval() const;void polar_mode();//set mode to POLvoid rect_mode();//set mode to RECT//operator overloadingVector operator+(const Vector& b) const;Vector operator-(const Vector& b)const;Vector operator-()const;Vector operator*(double n) const;//friendsfriend Vector operator* (double n, const Vector& a);friend std::ostream&operator<< (std::ostream& os, const Vector& v);};
}

vect.cpp

#include "vect.h"namespace VECTOR
{//compute degrees in one radianconst double Rad_to_Deg = 45.0 / atan(1.0);//about 57.2957795130823//private methods, calculating magnitude from x and y//set x from polar coordinatevoid Vector::set_x(double mag, double ang){x = mag * cos(ang);}//set y from polar coordinatevoid Vector::set_y(double mag, double ang){y = mag * sin(ang);}double Vector::magval() const{return sqrt(x * x + y * y);}double Vector::angval() const{if (x == 0.0 && y == 0.0){return 0.0;}else{return atan2(y, x);}}//public methods Vector::Vector()//default constructor{x = y = 0.0;mode = RECT;}//constructor vector from rectangular coordinates if form is r//(the default) or else from polar coordinate if form is pVector::Vector(double n1, double n2, Mode form){mode = form;if (form == RECT){x = n1;y = n2;}else if (form == POL){set_x(n1, n2 / Rad_to_Deg);set_y(n1, n2 / Rad_to_Deg);}else{cout << "Incorrect 3rd argument to Vector()--";cout << "vector set to 0n";x = y = 0.0;mode = RECT;}}//reset vector from rectangular coordinates if form is RECT//or else from polar coordinates if form is POLvoid Vector::reset(double n1, double n2, Mode form){mode = form;if (form == RECT){x = n1;y = n2;}else if (form == POL){set_x(n1, n2 / Rad_to_Deg);set_y(n1, n2 / Rad_to_Deg);}else{cout << "Incorrect 3rd argument to Vector()--";cout << "vector set to 0n";x = y = 0.0;mode = RECT;}}//dectructorVector::~Vector(){}//set to polar modevoid Vector::polar_mode(){mode = POL;}//set to rectangular modevoid Vector::rect_mode(){mode = RECT;}//operator overloading//add two VectorsVector Vector::operator+(const Vector& b) const{return Vector(x + b.x, y + b.y);}//subtract Vector b from aVector Vector::operator-(const Vector& b) const{return Vector(x - b.x, y - b.y);}//reverse sign of VectorVector Vector::operator-() const{return Vector(-x, -y);}//multiply vector by nVector Vector::operator*(double n) const{return Vector(n * x, n * y);}//friend methods//multiply n by Vector aVector operator*(double n, const Vector& a){return a * n;}//display rectangular coordinates if mode is RECT, //else display polar coordinates if mode is POLstd::ostream& operator<<(std::ostream& os, const Vector& v){if (v.mode == Vector::RECT){os << "(x,y) = (" << v.x << "," << v.y << ")";}else if (v.mode == Vector::POL){os << "(m,a) = (" << v.magval() << "," << v.angval() * Rad_to_Deg << ")";}else{os << "Vector object mode is invalid";}return os;}
}

main.cpp

#include "vect.h"int main(void)
{using VECTOR::Vector;srand(time(0));double direction;Vector step;Vector result(0.0, 0.0);unsigned long steps = 0;double target;double dstep;cout << "Enter target distance(q to quit):";while (cin >> target){cout << "Enter step length:";if (!(cin >> dstep)){break;}while (result.magval() < target){direction = rand() % 360;//1至set(dstep, direction, Vector::POL);result = result + step;steps++;}cout << "After " << steps << " steps, the subject has the following location:n";cout << result << endl;result.polar_mode();cout << " orn" << result << endl;cout << "Average outward distance per step = " << result.magval() / steps << endl;steps = set(0.0, 0.0);cout << "Enter target distance(q to quit):";}cout << "Bye!" << endl;cin.clear();while (() != 'n'){continue;}return 0;
}

3.修改程序清单11.15,使之报告N次测试中的最高、最低和平均步数(其中N是用户输入的整数),而不是报告每次测试的结果。

#include "vect.h"int main(void)
{using VECTOR::Vector;srand(time(NULL));double direction;Vector step;Vector result(0.0, 0.0);unsigned long steps = 0;double target;double dstep;unsigned int N;			//用户输入的次数unsigned int max = 0;	//最高步数unsigned int min = 0;	//最低步数unsigned int sum = 0;	//平均步数cout << "How many times do you want to try? :";cin >> N;cout << "Enter target distance:";cin >> target;cout << "Enter step length:";cin >> dstep;for (int i = 0; i < N; i++){while (result.magval() < target){direction = rand() % 360;//1至set(dstep, direction, Vector::POL);result = result + step;steps++;}max = (max > steps) ? max : steps;if (min == 0)//第一次运行时{min = max;}else{min = (min < steps) ? min : steps;}sum += steps;steps = set(0.0, 0.0);}cout << "Max steps:" << max << endl;cout << "Min steps:" << min << endl;cout << "Average steps:" << (double)sum / N << endl;cout << "Bye!" << endl;cin.clear();while (() != 'n'){continue;}return 0;
}

4.重新编写最后的Time类示例(程序清单11.10、程序清单11.11、程序清单11.12),使用友元函数来实现所有的重载运算符。
实现:
time.h

#pragma once#include <iostream>class Time
{
private:int hours;int minutes;
public:Time();Time(int h, int m = 0);void AddMin(int m);void AddHr(int h);void Reset(int h = 0, int m = 0);friend Time operator+(const Time& t1, const Time& t2);	//->友元friend Time operator-(const Time& t1, const Time& t2);	//->友元friend Time operator*(const Time& t1, double n);		//->友元friend Time operator*(double m, const Time& t) { return t * m; }//inline definitionfriend std::ostream& operator<< (std::ostream& os, const Time& t);};

time.cpp

#include "time.h"Time::Time()
{hours = minutes = 0;
}Time::Time(int h, int m)
{hours = h;minutes = m;
}void Time::AddMin(int m)
{minutes += m;hours += minutes / 60;minutes %= 60;
}void Time::AddHr(int h)
{hours += h;
}void Time::Reset(int h, int m)
{hours = h;minutes = m;
}Time operator+(const Time& t1, const Time& t2)
{Time time;time.minutes = t1.minutes + t2.minutes;time.hours = t1.hours + t2.hours + time.minutes / 60;time.minutes = time.minutes % 60;return time;
}Time operator-(const Time& t1, const Time& t2)
{Time diff;int total1, total2;total1 = t1.minutes + 60 * t1.hours ;total2 = t2.minutes + 60 * t2.hours;diff.hours = (total2 - total1) / 60;diff.minutes = (total2 - total1) % 60;return diff;
}Time operator*(const Time& t1, double n)
{Time result;long totalminutes = t1.hours * n * 60 + t1.minutes * n;result.hours = totalminutes / 60;	//商result.minutes = totalminutes % 60;	//余数return result;
}std::ostream& operator<<(std::ostream& os, const Time& t)
{os << t.hours << " hours, " << t.minutes << " minutes";return os;
}

5.重新编写Stonewt类(程序清单11.16和程序清单11.17),使它有一个状态成员,由该成员控制对象应转换为英石格式、整数磅格式还是浮点磅格式。重载<<运算符,使用它来替换show_stn()和show_lbs()方法。重载加法、减法和乘法运算符,以便可以对Stonewt值进行加、减、乘运算。编写一个使用所有类方法和友元的小程序,来测试这个类。
实现:
stonewt.h

#pragma once
#include <iostream>
using namespace std;
class Stonewt
{
public:enum Type{STONE, POUNDS, FLOATPOUNDS};
private:enum { Lbs_per_stn = 14 };		//pounds per stoneint stone;						//whole stonesdouble pds_left;				//fractional poundsdouble pounds;					//entire weight in poundsType type;
public:Stonewt(double lbs);			//constructor for double poundsStonewt(int stn, double lbs);	//constructor for stone, lbsStonewt();						//default constructor~Stonewt();void SetType(Type m);Stonewt operator+(const Stonewt&s)const;Stonewt operator-(const Stonewt& s)const;Stonewt operator*(double n)const;friend ostream& operator<< (ostream& os, const Stonewt& s);//cout << stone; 
};

stonewt.cpp

#include "stonewt.h"Stonewt::Stonewt(double lbs)
{stone = int(lbs) / Lbs_per_stn;pds_left = int(lbs) % Lbs_per_stn + lbs - int(lbs);pounds = lbs;
}Stonewt::Stonewt(int stn, double lbs)
{stone = stn;pds_left = lbs;pounds = stn * Lbs_per_stn + lbs;
}Stonewt::Stonewt()
{stone = pounds = pds_left = 0;
}Stonewt::~Stonewt()
{
}void Stonewt::SetType(Type m)
{type = m;
}Stonewt Stonewt::operator+(const Stonewt& s) const
{return Stonewt(pounds + s.pounds);
}Stonewt Stonewt::operator-(const Stonewt& s) const
{return Stonewt(pounds - s.pounds);;
}Stonewt Stonewt::operator*(double n) const
{return Stonewt(pounds * n);
}ostream& operator<<(ostream& os, const Stonewt& s)
{if (s.type == Stonewt::STONE){os << s.stone << " stone, " << s.pds_left << " pounds" << endl;}else pe == Stonewt::POUNDS){os << int(s.pounds) << " pounds" << endl;}else if (s.type == Stonewt::FLOATPOUNDS){os << s.pounds << " pounds" << endl;}else{os << "Invalid type" << endl;}return os;
}

main.cpp

#include "stonewt.h"int main(void)
{Stonewt incognito = 275;Stonewt wolfe(285.7);Stonewt taft(21, 8);incognito.SetType(Stonewt::POUNDS);cout << "incognito:" << incognito;wolfe.SetType(Stonewt::FLOATPOUNDS);cout << "wolfe:" << wolfe;taft.SetType(Stonewt::STONE);cout << "taft:" << taft;taft = incognito + wolfe;taft.SetType(Stonewt::STONE);cout << "incognito + wolfe = :" << taft;taft = wolfe - incognito;taft.SetType(Stonewt::FLOATPOUNDS);cout << "wolfe - incognito = :" << taft;incognito = incognito * 2;incognito.SetType(Stonewt::POUNDS);cout << "incognito * 2 = :" << incognito;return 0;
}

6.重新编写Stonewt类(程序清单11.16和程序清单11.17),重载全部6个关系运算符。运算符对pounds成员进行比较,并返回一个bool值。编写一个程序,它声明一个包含6个Stonewt对象的数组,并在数组声明中初始化前3个对象。然后使用循环来读取用于设置剩余3个数组元素的值。接着报告最小的元素、最大的元素以及大于或等于11英石的元素的数量(最简单的方式是创建一个Stonewt对象,并将其初始化为11英石,然后将其同其他对象进行比较。)
实现:
stonewt.h

#pragma once
#include <iostream>
using namespace std;class Stonewt
{
private:enum { Lbs_per_stn = 14 };		//pounds per stoneint stone;						//whole stonesdouble pds_left;				//fractional poundsdouble pounds;					//entire weight in pounds
public:Stonewt(double lbs);			//constructor for double poundsStonewt(int stn, double lbs);	//constructor for stone, lbsStonewt();						//default constructor~Stonewt();bool operator<(const Stonewt& s)const;bool operator<=(const Stonewt& s)const;bool operator>(const Stonewt& s)const;bool operator>=(const Stonewt& s)const;bool operator==(const Stonewt& s)const;bool operator!=(const Stonewt& s)const;void show_lbs()const;			//show weight in pounds formatvoid show_std()const;			//show weight in stone format
};

stonewt.cpp

#include "stonewt.h"Stonewt::Stonewt(double lbs)
{stone = int(lbs) / Lbs_per_stn;pds_left = int(lbs) % Lbs_per_stn + lbs - int(lbs);pounds = lbs;
}Stonewt::Stonewt(int stn, double lbs)
{stone = stn;pds_left = lbs;pounds = stn * Lbs_per_stn + lbs;
}Stonewt::Stonewt()
{stone = pounds = pds_left = 0;
}Stonewt::~Stonewt()
{
}bool Stonewt::operator<(const Stonewt& s) const
{return pounds < s.pounds;
}bool Stonewt::operator<=(const Stonewt& s) const
{return pounds <= s.pounds;
}bool Stonewt::operator>(const Stonewt& s) const
{return pounds > s.pounds;
}bool Stonewt::operator>=(const Stonewt& s) const
{return pounds >= s.pounds;
}bool Stonewt::operator==(const Stonewt& s) const
{return pounds == s.pounds;
}bool Stonewt::operator!=(const Stonewt& s) const
{return pounds != s.pounds;}void Stonewt::show_lbs() const
{cout << stone << " stone, " << pds_left << " pounds" << endl;
}void Stonewt::show_std() const
{cout << pounds << " pounds" << endl;
}

main.cpp

#include "stonewt.h"
const int SIZE = 6;int main(void)
{double input;Stonewt stonewt_arr[SIZE] = { 275,Stonewt(285.7),Stonewt(21,8) };//初始化前3个Stonewt max_pounds = stonewt_arr[0];//最大的值Stonewt min_pounds = stonewt_arr[0];//最小的值Stonewt eleven = Stonewt(11, 0.0);  //11英石unsigned int count = 0;for (int i = 3; i < SIZE; i++){cout << "Enter number" << i + 1 << " element of stonewt_arr(in pounds)" << endl;cin >> input;stonewt_arr[i] = Stonewt(input);}for (int i = 0; i < SIZE; i++){max_pounds = (max_pounds > stonewt_arr[i]) ? max_pounds : stonewt_arr[i];min_pounds = (min_pounds < stonewt_arr[i]) ? min_pounds : stonewt_arr[i];if (stonewt_arr[i] > eleven){count++;}}cout << "The max weight is: ";max_pounds.show_std();cout << "The min weight is: ";min_pounds.show_std();cout << count << " objects are heavier than eleven." << endl;return 0;
}

7.复数由两个部分组成:实数部分和虚数部分。复数的一种书写方式是:(3.0, 4.0),其中3.0是实数部分,4.0是虚数部分。假设a=(A,Bi),c = (C, Di),则下面是一些复数运算。

加法:a + c = (A + C, (B+D)i)。
减法:a - c = (A - C, (B-D)i)。
乘法:a * c = (A *C - B*D, (A*d + B*C)i)。
乘法:x*c = (x*C, x * Di),其中x为实数。
共轭:~a = (A, -Bi)。

请定义一个复数类,以便下面的程序可以使用它来获得正确的结果。

#include <iostream>
using namespace std;
#include "complex0.h"    // to avoid confusion with complex.h
int main()
{complex a(3.0, 4.0); // initialize to (3,4i)complex c;cout << "Enter a complex number (q to quit):n";while (cin >> c){cout << "c is " << c << 'n';cout << "complex conjugate is " << ~c << 'n';cout << "a is " << a << 'n";cout << "a + c is " << a + c << 'n';cout << "a - c is " << a - c << 'n';cout << "a * c is " << a * c << 'n';cout << "2 * c is " << 2 * c << 'n';cout << "Enter a complex number (q to quit):n";}cout << "Done!n";return 0;
}

注意,必须重载运算符<<和>>。标准C++使用头文件complex提供了比这个示例更广泛的复数支持,因此应将自定义的头文件名为complex0.h,以免发生冲突。应尽可能使用const。
下面是该程序的运行情况。

Enter a complex number (q to quit):
real: 10
imaginary: 12
c is (10,12i)
complex conjugate is (10,-12i)
a is (3,4i)
a + c is (13,16i)
a - c is (-7,-8i)
a * c is (-18,76i)
2 * c is (20,24i)
Enter a complex number (q to quit):
real: q
Done!

请注意,经过重载后,cin >> c将提示用户输入实数和虚数部分。

实现:
complex0.h

#pragma once
#include <iostream>
using namespace std;class complex0
{
public:complex0();complex0(double r, double i);~complex0();complex0 operator+(const complex0& c)const;complex0 operator-(const complex0& c)const;complex0 operator*(const complex0& c)const;friend complex0 operator*(double x, const complex0& c);complex0 operator~()const;//共轭friend istream& operator>>(istream &is, complex0& c);friend ostream& operator<<(ostream& os, const complex0& c);private:double real;//实数double imaginary;//虚数
};

complex0.cpp

#include "complex0.h"complex0::complex0()
{real = imaginary = 0.0;
}complex0::complex0(double r, double i)
{real = r;imaginary = i;
}complex0::~complex0()
{real = imaginary = 0.0;
}complex0 complex0::operator+(const complex0& c) const
{return complex0(real + c.real, imaginary + c.imaginary);
}complex0 complex0::operator-(const complex0& c) const
{return complex0(real - c.real, imaginary - c.imaginary);
}complex0 complex0::operator*(const complex0& c) const
{return complex0(real * c.real - imaginary*c.imaginary, real * c.imaginary + imaginary * c.real);
}complex0 complex0::operator~() const
{return complex0(real, -imaginary);
}complex0 operator*(double x, const complex0& c)
{return complex0(x * c.real, x * c.imaginary);
}istream& operator>>(istream& is, complex0& c)
{cin >> c.real >> c.imaginary;return is;
}ostream& operator<<(ostream& os, const complex0& c)
{cout << "real = " << c.real << ", imaginary = " << c.imaginary << endl;return os;
}

本文发布于:2024-01-28 15:13:19,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/17064260038312.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:一章
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23