有这样一个醉汉,他每迈出一步的步长是不变的,但是迈步的朝向是不确定的(假设在360°内随机),请问他需要走多少步才能距离出发点50米?
Vector中定义了一个比较完整的向量运算类,其中有很多方法在解决这个问题的时候并没有使用到
头文件:
#ifndef VECTOR_H_
#define VECTOR_H_
#include <iostream>
//本类提供了主要是针对向量参数储存及其操作。提供了向量数据直角坐标系和极坐标系两种储存方法。可以初始化一个向量,使用向量对象的x,y,angle,magnitude,对两个向量对象进行+,-,*运算以及打印向量等操作。
namespace VECTOR
{
class Vector
{
//使用枚举定义两种模式
public:
enum Mode{RECT, POL};
//定义私有数据
private:
double x;
double y;
double ang;
double mag;
//定义私有函数,用来同步直角坐标系与极坐标系两者坐标
void set_pol();
void set_rect();
//定义公共数据与函数
public:
//构造函数与析构函数
Vector();
Vector(const double n1, const 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; }
//运算符重构函数
Vector operator+(const Vector& b) const;
Vector operator-(const Vector& b) const;
//取负运算符(计算原点对称点)
Vector operator-() const;
//在向量后乘一个系数
Vector operator*(double n) const;
//向量点乘运算
double operator*(const Vector& b);
//向量叉乘运算
Vector operator^(const Vector& b);
//下面的是友元函数
//在向量前乘一个系数
friend Vector operator*(double n, const Vector& a);
//重构输出流运算符
friend std::ostream& operator<<(std::ostream& os, const Vector& v);
//可以对象调用的输出函数
void show();
void read_to_text(std::ostream& os);
};
}
#endif
实现文件:
#include "11.5.0.h"
#include <cmath>
using std::sqrt;
using std::sin;
using std::cos;
using std::atan;
using std::atan2;
using std::cout;
using std::endl;
namespace VECTOR
{
const double Rad_to_deg = 45.0 / atan(1.0);
void Vector::set_pol()
{
mag = sqrt(x * x + y * y);
if (x == 0.0 && y == 0.0)
ang = 0.0;
else
ang = atan2(y, x);
}
void Vector::set_rect()
{
x = mag * cos(ang);
y = mag * sin(ang);
}
Vector::Vector()
{
x = 0.0;
y = 0.0;
ang = 0.0;
mag = 0.0;
}
Vector::Vector(const double n1, const double n2, Mode form)
{
if (form == RECT)
{
x = n1;
y = n2;
set_pol();
}
else
{
mag = n1;
ang = n2;
set_rect();
}
}
void Vector::reset(double n1, double n2, Mode form)
{
if (form == RECT)
{
x = n1;
y = n2;
set_pol();
}
else
{
mag = n1;
ang = n2;
set_rect();
}
}
Vector::~Vector()
{
}
Vector Vector::operator+(const Vector& b) const
{
/*Vector sum;
sum.x = x + b.x;
sum.y = y + b.y;
sum.set_pol();
return sum;*/
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);
}
double Vector::operator*(const Vector& b)
{
return (x * b.x + y * b.y);
}
Vector Vector::operator^(const Vector& b)
{
return Vector(x * b.y - y * b.x, x * b.y + y * b.x);
}
Vector operator*(double n, const Vector& a)
{
return Vector(n * a.x, n * a.y);
}
std::ostream& operator<<(std::ostream& os, const Vector& v)
{
os << "(x,y) = " << "(" << v.x << "," << v.y << ")" << " ; "
<< "(D,A) = " << "(" << v.mag << "," << v.ang << ")" << endl;
return os;
}
void Vector::show()
{
cout << *this;
}
void Vector::read_to_text(std::ostream& os)
{
os << *this;
}
Vector::operator double()
{
return this->mag;
}
}
主文件:
//主要是使用前面定义的Vector类进行一些向量有关的计算,模拟醉鬼走路问题,要求输入距离,输入每步距离,计算总步数与位置,每一步角度随机。
//现在可以指定进行多少次实验,并输出每次实验的步数与最终的最大值,最小值和平均值
#include "11.5.0.h"
#include <random>
#include <cstdlib>
#include <ctime>
#include <fstream>
using namespace std;
using VECTOR::Vector;
int main()
{
double distance = 0;
double distance_per = 0;
double distance_sum = 0;
int step = 0;
int maxStep = 0;
int minStep = 0;
int sumStep = 0;
double averStep = 0;
int testTimes = 1;
Vector sum;
Vector perStep;
srand(time(0));
ofstream cfout;
cfout.open("11.5.0.text");
cout << "请输入执行次数:";
while (cin >> testTimes && testTimes != 0)
{
cin.get();
cout << "请输入总距离:";
cin >> distance;
cin.get();
cout << "请输入每一步的长度:";
cin >> distance_per;
cin.get();
for (int i = 0; i < testTimes; i++)
{
for (; distance_sum < distance; step++)
{
perStep.reset(distance_per, rand() % 360, VECTOR::Vector::Mode::POL);
perStep.read_to_text(cfout);
sum = sum + perStep;
distance_sum = sum.magval();
}
cout << "第" << i + 1 << "次实验" << "走了" << step << "步" << endl;
if (i == 0)
{
maxStep = step;
minStep = step;
sumStep = step;
}
else
{
if (step > maxStep)
maxStep = step;
if (step < minStep)
minStep = step;
sumStep += step;
}
distance_sum = 0;
step = 0;
sum = Vector();
}
averStep = double(sumStep) / testTimes;
cout << "最大值是:" << maxStep << endl
<< "最小值是:" << minStep << endl
<< "平均值是:" << averStep << endl;
cout << "请输入执行次数:";
}
}
执行结果:
请输入执行次数:10
请输入总距离:50
请输入每一步的长度:1
第1次实验走了1854步
第2次实验走了1132步
第3次实验走了1372步
第4次实验走了1921步
第5次实验走了1106步
第6次实验走了721步
第7次实验走了2482步
第8次实验走了1074步
第9次实验走了2458步
第10次实验走了1302步
最大值是:2482
最小值是:721
平均值是:1542.2
后面的具体细节省略
请输入执行次数:50
请输入总距离:50
请输入每一步的长度:1
最大值是:9216
最小值是:584
平均值是:2637.4
请输入执行次数:100
请输入总距离:50
请输入每一步的长度:1
最大值是:11059
最小值是:273
平均值是:2415.05
请输入执行次数:1000
请输入总距离:50
请输入每一步的长度:1
最大值是:14005
最小值是:348
平均值是:2475.22
请输入执行次数:0
E:\computer learning\The basics\C++\code\code\x64\Debug\code.exe (进程 20040)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .
可以看到,随着试验次数的不断增加,最终大约经过2475步才能走出50米。