C++Primer Plus第十一章类的使用,课后练习1,还是醉汉回家的故事

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

vector.h

#pragma once
//vect.h -- Vector class with <<,mode state
#ifndef	VECTOR_H_	
#define VECTOR_H_

#include<iostream>
namespace VECTOR
{
	class Vector
	{
	public:
		enum Mode { RECT, POL };//以此为直角坐标,极坐标(长度,角度)
		//RECT for rectangular,POL for Polar modes
	private:
		double x;//horizontal value x方向x坐标
		double y;//vertical value  y方向y坐标
		double mag; //length of value  极坐标的长度
		double ang;//direction of vector in degrees,极坐标的角度
		Mode mode;//RECT or POL
		//private methods for setting values
		void set_mag();
		void set_ang();
		void set_x();
		void set_y();
	public:
		Vector();
		Vector(double x, double y, Mode form = RECT);
		void reset(double x, double y, Mode form = RECT);
		~Vector();
		double xval()const { return x; }//report x val
		double yval()const { return y; }//report y val
		double magVal()const { return mag; }//report magnitude
		double angval()const { return ang; }//report angle
		void polar_mode();//set mode to POL
		void rect_mode();//set mode to RECT
		//operator overloading 
		Vector operator+(const Vector& b)const;
		Vector operator-(const Vector& b)const;
		Vector operator-()const;
		Vector operator*(double n)const;
		//friends
		friend Vector operator*(double n, const Vector& a);
		friend std::ostream& operator<<(std::ostream& os, const Vector& v);
	};// end Vector
}//end namespace VECTOR

#endif

vetor.cpp

//vect.cpp == methods for the Vector class
#include<cmath>	
#include"vector.h" //includes<iostream>
using std::sqrt;
using std::sin;
using std::cos;
using std::atan;
using std::atan2;
using std::cout;
using std::endl;

namespace VECTOR
{
	//comput degrees in one radian 
	const double Rad_to_deg = 45.0 / atan(1.0);
	//should be about 57.2957795130823

	//private methods
	//calculates magnitude from x and y 
	void 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 coorinate 
	void Vector::set_x()
	{
		x = mag * cos(ang);
	}
	//set y from polar coorinate
	void Vector::set_y()
	{
		y = mag * sin(ang);
	}
	//public methods 
	//default constructor
	Vector::Vector()
	{
		y = x = mag = ang = 0.0;
		mode = RECT;
	}

	//construct vector from rectangular coordinates if form is r 
	//(the default) or else from polay coordinates if form is p
	Vector::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_mag();
			set_ang();
		}
		else
		{
			cout << "Incorrect 3rd argument to Vector() -- ";
			cout << "vector set to 0\n";
			x = y = mag = ang = 0.0;
			mode = RECT;
		}
	}
	//reset vector from rectangular coorinates if form is 
	//RECT(the default) or else from polar coorinates if 
	//form is POL
	void 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 0\n";
			x = y = mag = ang = 0.0;
			mode = RECT;
		}
	}
	Vector::~Vector()//destructor
	{

	}

	void Vector::polar_mode()//set to polay mode 
	{
		mode = POL;
	}

	void Vector::rect_mode() // set to rectangular mode
	{
		mode = RECT;
	}

	//operator overloading 
	//add two Vectors 
	Vector Vector::operator+(const Vector& b)const
	{
		return Vector(x + b.x, y + b.y);
	}
	//sub vector b from a 
	Vector Vector::operator-(const Vector& b)const
	{
		return Vector(x - b.x, y - b.y);
	}

	//reverse sign of Vector
	Vector Vector::operator-()const
	{
		return Vector(-x, -y);
	}

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

	//friend methods
	//multiply n by Vector a 
	Vector operator*(double n, const Vector& a)
	{
		return a * n;
	}

	//display rectangular coorinates if mode is RECT
	//else display polar coordinates if mode is POL
	std::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;
	}
}//end namespace VECTOR

main.cpp

#if 1
#include <iostream>
#include<cstdlib>	//rand,srand() prototypes
#include<ctime>//time()prototype
#include<fstream>
#include"vector.h"
int main()
{
	using namespace std;
	using VECTOR::Vector;
	ofstream of;
	of.open("ofoutput.txt");
	srand(time(0));//seed random-number generator 
	double direction;
	Vector step;
	Vector result(0.0, 0.0);
	unsigned long steps = 0;
	double target;
	double dstep;
	cout.setf(ios_base::fixed, ios_base::floatfield);
	cout.precision(2);
	of.setf(ios_base::fixed, ios_base::floatfield);
	of.precision(2);
	cout << "Enter target distance(q to quit):";
	of << "Enter target distance(q to quit):";
	while (cin >> target)
	{
		of << target << ", ";
		cout << "Enter step length: ";
		of << "Enter step length: ";
		if (!(cin >> dstep))
		{
			break;
		}
		of << dstep<<endl;
		while (result.magVal() < target)
		{
			cout  << steps << "\t: (x,y) = (" << result.xval()<<"    " << result.yval() << ")" << endl;
			of    << steps << "\t: (x,y) = (" << result.xval() << "    " << result.yval() << ")" << endl;
			direction = rand() % 360;
			step.reset(dstep, direction, Vector::POL);
			result = result + step;
			steps++;
		}
		cout << steps << ": (x,y) = (" << result.xval() << "    " << result.yval() << ")" << endl;
		of   << steps << ": (x,y) = (" << result.xval() << "    " << result.yval() << ")" << endl;
		cout << "After " << steps << " steps,the subject " "has the following location:\n";
		of << "After " << steps << " steps,the subject " "has the following location:\n";
		cout << result << endl;
		of << result << endl;
		result.polar_mode();
		cout << " or\n" << result << endl;
		of << " or\n" << result << endl;
		cout << "Average outward distance per step = "<< result.magVal() / steps << endl;
		of << "Average outward distance per step = " << result.magVal() / steps << endl;
		steps = 0;
		result.reset(0.0, 0.0);
		cout << "Enter target distance(q to quit): ";
		of << "Enter target distance(q to quit): ";
	}
	cout << "Bye!\n";
	cin.clear();
	while (cin.get() != '\n')
	{
		continue;
	}
	cout.unsetf(cout.flags());
	of.unsetf(cout.flags());
	of.close();
	return 0;
}
#endif

实验结果
在这里插入图片描述

总结:
1,在11.5程序清单中已经实现过。
2,增加文件处理的类ofstream,打开文件,关闭文件
3,增加格式化控制cout.setf(ios_base::fixed, ios_base::floatfield);
cout.precision(2);cout.unsetf(cout.flags());
4,这种处理的随机性使得每次运行结果都不同,即使初始条件相同。然而,平均而言,步长减半,步数将为原来的4倍。概率理论表明,平均而言,步数(N)、步长(s),净距离D之间的关系如下:
N=(D/s)的N次方
5,做这种练习锻炼思维为日后编程打下扎实的基础

  • 10
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值