C++ Primer Plus(6th edition)课后习题第11章使用类

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

//randwalk.cpp
#include<iostream>

#include<cstdlib>   //rand(),srand()原型

#include<ctime>     //time()原型

#include<fstream>

#include"vect.h" 

using namespace std;

int main()
{
	using VECTOR::Vector;
	srand(time(0));
	double direction;
	Vector step;
	Vector result(0.0, 0.0);
	unsigned long steps = 0;
	double target;
	double dstep;
	ofstream fout;
	fout.open("savesteps.txt");
	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 << endl;
		while (result.magval() < target)
		{
			fout << steps << ": " << result << endl;
			direction = rand() % 360;
			step.reset(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 << " or\n" << result << endl;
		cout << "Average outward distance per step = "
			<< result.magval() / steps << endl;

		fout << " or\n" << result << endl;
		fout << "Average outward distance per step = "
			<< result.magval() / steps << endl;
		steps = 0;
		result.reset(0.0, 0.0);
		cout << "Enter target distance (q to quit): ";
	}
	cout << "Bye!\n";
	cin.clear();
	while (cin.get() != '\n')
		continue;
	cin.get();
	return 0;
}

运行结果:

Target Distance: 90 Step Size: 8.9
0: (x,y) = (0, 0)
1: (x,y) = (7.0133, 5.47939)
2: (x,y) = (11.4633, -2.22824)
3: (x,y) = (6.35847, 5.06221)
4: (x,y) = (0.757514, -1.85438)
5: (x,y) = (9.5223, -0.308916)
6: (x,y) = (12.1244, 8.2022)
7: (x,y) = (20.9378, 6.96356)
8: (x,y) = (29.7026, 5.41809)

......

After 153 steps, the subject has the following location:
(x,y) = (91.3235, -37.0908)
 or
(m,a) = (98.5683, -22.1044)
Average outward distance per step = 0.644237

*题目核心在于:fout << steps << ": " << result << endl;

通过重载<<运算符使得在RECT模式下以(x,y)形式输出对应坐标到文件中。

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------

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

//vect.h
#ifndef VECTOR_H_
#define VECTOR_H_

#include <iostream>
#include <cmath>
#include <cstdlib>
#include <ctime>

using namespace std;

namespace VECTOR
{
	class Vector
	{
	public:
		enum Mode { RECT, POL };
	private:
		double x;
		double y;
		Mode mode;

		double set_mag()const;
		double set_ang()const;
		void 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 { return set_mag(); }
		double angval()const { return set_ang(); }
		void polar_mode();
		void rect_mode();

		Vector operator+(const Vector &b)const;
		Vector operator-(const Vector &b)const;
		Vector operator-()const;
		Vector operator*(double n)const;

		friend Vector operator*(double n, const Vector &a);
		friend ostream & operator<<(ostream &os, const Vector &v);
	};
}

#endif
vector.cpp
#include"vect.h"

namespace VECTOR
{
	const double Rad_to_deg = 45.0 / atan(1.0);

	double Vector::set_mag()const
	{
		return sqrt(x * x + y * y);
	}

	double Vector::set_ang()const
	{
		if (x == 0.0 && y == 0.0)
			return 0.0;
		else
			return atan2(y, x);
	}

	void Vector::set_x(double mag, double ang)
	{
		x = mag * cos(ang);
	}

	void Vector::set_y(double mag, double ang)
	{
		y = mag * sin(ang);
	}

	Vector::Vector()
	{
		x = y = 0.0;
		mode = RECT;
	}

	Vector::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 0\n";
			x = y = 0.0;
			mode = RECT;
		}
	}

	void 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 0\n";
			x = y = 0.0;
			mode = RECT;
		}
	}

	Vector::~Vector()
	{

	}

	void Vector::polar_mode()
	{
		mode = POL;
	}

	void Vector::rect_mode()
	{
		mode = RECT;
	}

	Vector Vector::operator+(const Vector &b)const
	{
		return Vector(x + b.x, y + b.y);
	}

	Vector Vector::operator-(const Vector &b)const
	{
		return Vector(x - b.x, y - b.y);
	}

	Vector Vector::operator-()const
	{
		return Vector(-x, -y);
	}

	Vector Vector::operator*(double n)const
	{
		return Vector(n*x, n*y);
	}

	Vector operator*(double n, const Vector &a)
	{
		return a * n;
	}

	ostream &operator<<(ostream &os, const Vector &v)
	{
		if (v.mode == Vector::RECT)
			os << "(x,y) = (" << v.x << ", " << v.y << ")";
		else if (v.mode == Vector::POL)
		{ 
			//更新:Vector类不不存储矢量长度和方向,改为被调用时计算
			os << "(m,a) = (" << v.set_mag() << ", "
				<< v.set_ang()*Rad_to_deg << ")"; 
		}
		else
			os << "Vector object mode is invalid";
		return os;
	}
}

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------

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

#include "vect.h"

int main()
{
	using VECTOR::Vector;
	srand(time(0));
	double direction;
	Vector step;
	Vector result(0.0, 0.0);
	unsigned long steps = 0;
	double target;
	double dstep;
	double numbers, N;
	double Min, Max, Sum, Average;
	cout << "Enter target distance: ";
	cin >> target;
	cout << "Enter step length: ";
	cin >> dstep;
	cout << "Enter test numbers: ";
	cin >> numbers;
	N = numbers;
	Min = Max = Sum = Average = 0.0;
	while (numbers)           //共进行numbers次测试
	{
		while (result.magval() < target)
		{
			direction = rand() % 360;
			step.reset(dstep, direction, Vector::POL);
			result = result + step;
			steps++;
		}
		cout << "After " << steps << " steps once a walk\n";
		if (Min == 0 || Max == 0)
			Min = Max = steps;
		if (Min > steps)
			Min = steps;       //如果最低记录被打破,更新
		if (Max < steps)
			Max = steps;      //如果最高纪录被打破,更新
		Sum += steps;
		numbers--;
		steps = 0;
		result.reset(0.0, 0.0);
	}      //while (numbers) 
	Average = Sum / N;
	cout << "Max steps is " << Max << endl;
	cout << "Min steps is " << Min << endl;
	cout << "Average steps is " << Average << endl;
	cout << "Bye!\n";
	cin.clear();
	while (cin.get() != '\n')
		continue;
	cin.get();
	return 0;
}

*题目核心:

		if (Min == 0 || Max == 0)
			Min = Max = steps;
		if (Min > steps)
			Min = steps;       //如果最低记录被打破,更新
		if (Max < steps)
			Max = steps;      //如果最高纪录被打破,更新

当进入while(numbers)循环,每轮将与上一轮进行比较。

程序运行结果:

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------

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

//mytime.h
#ifndef MYTIME_H_
#define MYTIME_H_

#include <iostream>
#include <string>
#include <stdio.h>

using namespace std;

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

	Time operator*(double n)const;
	friend Time operator-(const Time &t1, const Time &t2);
	friend Time operator+(const Time &t1, const Time &t2);
	friend Time operator*(double m, const Time &t)
	{
		return t * m;
	}
	friend ostream & operator<<(ostream & os, const Time &t);
};

#endif
//mytime.cpp

#include "mytime.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 sum;
	sum.minutes = t1.minutes + t2.minutes;
	sum.hours = t1.hours + t2.hours + sum.minutes / 60;
	sum.minutes %= 60;
	return sum;
}

Time operator-(const Time &t1, const Time &t2)
{
	Time diff;
	int tot1, tot2;
	tot1 = t1.minutes + 60 * t1.hours;
	tot2 = t2.minutes + 60 * t2.hours;
	diff.minutes = (tot1 - tot2) % 60;
	diff.hours = (tot1 - tot2) / 60;
	return diff;
}

Time Time::operator*(double mult)const
{
	Time result;
	long totalminutes = hours * mult * 60 + minutes * mult;
	result.hours = totalminutes / 60;
	result.minutes = totalminutes % 60;
	return result;
}

ostream &operator<<(ostream &os, const Time &t)
{
	os << t.hours << " hours, " << t.minutes << " minutes";
	return os;
}
//usetime.cpp

#include "mytime.h"

int main()
{
	Time aida(3, 35);
	Time tosca(2, 48);
	Time temp;

	cout << "Aida and Tosca:\n";
	cout << aida << "; " << tosca << endl;
	temp = aida + tosca;
	cout << "Aida + Tosca: " << temp << endl;
	temp = aida - tosca;
	cout << "Aida - Tosca: " << temp << endl;
	temp = aida * 1.17;
	cout << "Aida * 1.17: " << temp << endl;
	cout << "10.0 * Tosca: " << 10.0 * tosca << endl;

	cin.get();
	return 0;
}

第11章其他练习题请参阅完整代码:

下载链接:

https://download.csdn.net/download/ezra1991/10722513

猜你喜欢

转载自blog.csdn.net/Ezra1991/article/details/83064855