• 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
    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	
    #include"vector.h" //includes
    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 
    #include	//rand,srand() prototypes
    #include//time()prototype
    #include
    #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,做这种练习锻炼思维为日后编程打下扎实的基础

  • 相关阅读:
    Workfine新手入门:日期间隔函数范围判断
    线性代数的一些知识点
    下拉框判断是否重复选中值
    登录注册页面的模拟
    CDC一键入湖:当 Apache Hudi DeltaStreamer 遇见 Serverless Spark
    Spring IOC 和 AOP
    APCS (Arm Procedure Call Standard) 过程调用标准
    钉钉小程序 没有调用该接口的权限
    Scala学习:类和对象
    PyQt5 QLabel控件
  • 原文地址:https://blog.csdn.net/zhyjhacker/article/details/139359847