[英]Storing (x,y) point into array
I am trying to store a point into an array. 我试图将一个点存储到数组中。 The array has to be a size of 10 and the points have to be a random number from 0 to 100. I am going to be using this array and then organize it through quick sort, and figure out which points are the closest together. 数组的大小必须为10,点必须是0到100之间的随机数。我将使用此数组,然后通过快速排序对其进行整理,并找出哪些点最接近。 Doing some research I found that the Utility class has something that I think will work so I am trying to find out how to make the array generate with random points. 做一些研究后,我发现Utility类有一些我认为可以起作用的东西,因此我试图找出如何使数组生成带有随机点的方法。 One thing is I need the array to be either pass by reference or however way just to make sure I can have this array in main. 一件事是我需要通过引用传递数组,或者以确保我可以在主数组中传递的方式传递数组。
#include <iostream>
#include "qsort.h"
#include <stdlib.h>
#include <utility>
using namespace std;
const int ARRAY_SIZE = 10;
void initializePairs(pair<int,int> array);
int main()
{
//pair<int, int> shortPointArray[ARRAY_SIZE];
/*pair<int,int> temp = make_pair(5,6);
pair<int,int> shortPointArray[1];
shortPointArray[0] = temp;*/
pair<int,int> shortPointArray[1];
//qsort sorting;
initializePairs(shortPointArray);
return 1;
}
void initializePairs(pair<int,int> array)
{
int x;
int y;
pair<int,int> temp;
for(int i = 0; i < ARRAY_SIZE; i++)
{
x = rand() % 100;
y = rand() % 100;
temp = make_pair(x,y);
array[i] = temp;
}
}
It isn't all to hard to do what you are looking for: 要做您要寻找的并非全部:
main.cpp main.cpp
#include <iostream>
#include <vector>
#include <algorithm>
#include <random>
#include "Point.h"
int main() {
std::random_device rd; // Random Device: Used To Seed Mersenne Random Generator
std::mt19937 gen; // Mersenne Twister
gen.seed( rd() ); // Seed The Generator
std::uniform_int_distribution<> dist(0, 100); // Uniform Int Distribution between [a, max]
// Point<int>
std::vector<Point<int>> points;
points.reserve( NUM_POINTS );
for ( std::size_t i = 0; i < NUM_POINTS; i++ ) {
// Instead of creating a temporary stack copy each iteration
// I chose to use the constructor directly and instead of
// push_back, I'm using emplace_back.
// Point<int> p( dist( gen ), dist( gen ) );
// points.push_back( p );
points.emplace_back( Point<int>( dist( gen ), dist( gen ) ) );
}
std::cout << "Showing 10 points of type int with random (x,y):\n";
for ( auto& p : points ) {
std::cout << p;
}
std::cout << std::endl;
// Point<float>
std::vector<Point<float>> points2;
points.reserve( NUM_POINTS );
std::uniform_real_distribution<float> dist2( 0, 100.0f );
for ( std::size_t i = 0; i < NUM_POINTS; i++ ) {
// Instead of creating a temporary stack copy each iteration
// I chose to use the constructor directly and instead of
// push_back, I'm using emplace_back.
// Point<float> p( dist( gen ), dist( gen ) );
// points2.push_back( p );
points2.emplace_back( Point<float>( dist( gen ), dist( gen ) ) );
}
std::cout << "Showing 10 points of type float with random (x,y):\n";
for ( auto& p : points2 ) {
std::cout << p;
}
std::cout << std::endl;
// Sorting the containers:
std::sort( points.begin(), points.end() );
std::sort( points2.begin(), points2.end() );
std::cout << "Showing the sorted points with type int (x,y):\n";
for ( auto& p : points ) {
std::cout << p;
}
std::cout << std::endl;
std::cout << "Showing the sorted points with type float (x,y):\n";
for ( auto& p : points2 ) {
std::cout << p;
}
std::cout << std::endl;
std::cout << std::endl;
system( "PAUSE" );
return 0;
}
Point.h 点
#ifndef POINT_H
#define POINT_H
#include <iostream>
#include <tuple> // std::tie
const std::size_t NUM_POINTS { 10 };
// Need class Point prototype for operator<< declaration
template<class> class Point;
// Need operator<< declaration for class template Point's friend declaration
template<class T>
std::ostream& operator<<( std::ostream& out, const Point<T>& );
// Class Declaration & Definition
template<class T>
class Point {
public:
T _x;
T _y;
Point() : _x( 0 ), _( 0 ) {}
Point( T x, T y ) : _x( x ), _y( y ) {}
Point( T& x, T& y ) : _x( x ), _y( y ) {}
Point( T* x, T* y ) : _x( *x ), _y( *y ) {}
// friend prototype: notice the extra <> in this declaration
// It tells the compiler that this friend function will be a specialization of this class template
friend std::ostream& operator<< <>( std::ostream& out, const Point<T>& p );
// operator< for comparison
bool operator<( Point<T>& p ) {
// std::tie makes it real easy to compare a (set) of values.
return std::tie( _x, _y ) < std::tie( p._x, p._y );
}
// operator> for comparison
bool operator<( Point<T>& p ) {
return !(*this < p );
}
// operator== for comparison
bool operator==( Point<T>& p ) {
return (this->_x == p._x && this->y == p._y );
}
};
// operator<< definition
template<class T>
std::ostream& operator<<( std::ostream& out, const Point<T>& p ) {
return out << "(" << p._x << "," << p._y << ")\n";
}
#endif // !POINT_H
As for the implementation of the class template Point<T>
you can refer to the comments in the header file. 至于类template Point<T>
的实现,可以引用头文件中的注释。
For the details of the main function I will go over some of those details. 有关主要功能的细节,我将介绍其中一些细节。
For generating your random values I would high suggest staying away from random()
or any of its related deprecated or soon to be functions. 为了生成您的随机值,我强烈建议您不要使用random()
或其相关的任何已弃用或即将成为函数的函数。 I would begin by learning and using Pseudo Random Generators that can be found in the standard library along with different types of distributions: these can all be found in <random>
header file. 我将从学习和使用伪随机生成器开始,这些伪随机生成器可以在标准库中找到以及不同类型的分布:所有这些都可以在<random>
头文件中找到。 You can use std::default_random_engine()
but I prefer to use std::random_device
We can use that to SEED
the engine(generator) of our choosing. 您可以使用std::default_random_engine()
但我更喜欢使用std::random_device
我们可以使用它来对我们选择的引擎(生成器)进行SEED
。 One of the more popularly used engines or generators is known as the Mersenne Twister
which is std::mt19937
and there is a 65bit version of it too. 一种更流行使用的引擎或发电机称为Mersenne Twister
,它的名称为std::mt19937
,它也有65位版本。 It is quite simple to do. 这很简单。
{
std::random_device rd; // create an instance of our device to seed with
std::mt19937 gen; // create an instance of our generator (engine)
gen.seed( rd() ); // This seeds the generator (engine)
// Now we need a distribution along with its data type
// there are different versions of these distributions for different types
// Some are for integral types while others are for floating point types
// Here we want a uniform distribution for int so we default the template
std::uniform_int_distribution<> dist(0, 100); //random from [0,100]
// otherwise we could of done
std::uniform_int_distribution<unsigned int> dist2( 0, 50 ); // random from [0, 50]
// There are other types of distributions
std::normal_distribution<> a;
std::poisson_distribution<> b;
// etc.
// If the distributions say "real" they are floating point types
std::uniform_real_distribution<float> f;
std::uniform_real_distribution<double> d;
// Just as there are different distributions there also other
// generators or engines beside the mersenne twister.
// There is another way besides using `random_device` to seed the generator
// you can use <chrono> header to use `std::chrono::high_resolution_clock
// to seed the generator
// You can also seed by const value
// and you can use std::seed_seq;
}
You can find all the information that you need for doing Pseudo Random Generators & Distributions from this web page. 你可以找到你需要从做伪随机发生器及分布的所有信息此网页。
So now that we have our random generators up and working the next step is we declare a std::vector<Point<int>>
then we use its reserve
function and set it with our const NUM_POINTS
. 因此,现在我们有了随机数生成器并开始下一步,我们声明一个std::vector<Point<int>>
然后使用其reserve
功能并将其设置为const NUM_POINTS
。 Then we go through a for loop for NUM_POINTS
iterations and we populate our container with a random (x,y)
set of values. 然后,我们进行NUM_POINTS
循环进行NUM_POINTS
次迭代,并用一组随机(x,y)
值填充容器。 Then we display the results using a ranged base for loop. 然后,我们使用范围为循环的底数显示结果。
I repeat the above process to show it being done with floats. 我重复以上过程以显示它是使用浮点数完成的。 I did it this way to show the usefulness of templates. 我这样做是为了展示模板的有用性。
After that I finally sort the containers simply by calling std::sort( begin, end )
using the vector's iterators. 之后,我最终使用向量的迭代器通过调用std::sort( begin, end )
来对容器进行std::sort( begin, end )
。 Then I go back and use a ranged base for loop to show both of the sorted vectors. 然后,我回过头来,使用循环范围的底数来显示两个排序的向量。
using std::sort works very easy since we defined an overloaded operator<()
for our class and we used std::tie to easily compare them. 使用std :: sort非常容易,因为我们为类定义了一个重载的operator<()
,并且我们使用了std :: tie来轻松比较它们。 This shows you the power of being of the standard library by bringing together a bunch of parts like set of Legos! 通过将诸如Legos套之类的许多零件组合在一起,可以向您展示成为标准库的力量!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.