Representing destinations in a square
Clash Royale CLAN TAG#URR8PPP
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;
up vote
3
down vote
favorite
I've written a program following the instructions of an exam paper. There are no solutions available so I would appreciate a feedback. I'm concerned with main
in particular (I've already posted a similar question here). I've tried to solve the problem as I've seen it's done in other solutions made available by our teacher. Also the constructors made me think a lot.
I was asked to make a program to represent destinations in a square [0,1]x[0,1], a salesman that has to go in some destinations in that square and another salesman inheriting from the former but with slightly different habits.
#include <iostream>
#include <vector>
#include <set>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstdlib>
class Location
private:
double x_, y_;
public:
Location(double x, double y) : x_(x), y_(y)
Location()
x_ = drand48();
y_ = drand48();
Location(const Location & L) : x_(L.x_), y_(L.y_)
double getx() return x_;
bool operator<(const Location & L) return x_ < L.x_;
double distance(const Location & L)
return std::sqrt(std::pow(x_ - L.x_, 2) + std::pow(y_ - L.y_, 2));
;
class Salesman
private:
Location start_;
protected:
std::vector<Location> tobevisited_;
public:
Salesman(const Location & start, std::vector<Location>::iterator it1, std::vector<Location>::iterator it2) : start_(start), tobevisited_(it1, it2)
int ndest() return tobevisited_.size();
virtual double visit()
double dist = 0;
sort(tobevisited_.begin(), tobevisited_.end());
dist = (*(tobevisited_.begin())).distance(start_);
for(std::vector<Location>::iterator it = tobevisited_.begin()+1; it != tobevisited_.end(); it++)
dist += (*(it)).distance(*(it-1));
return dist;
;
class LazySalesman : public Salesman
private:
double d_;
public:
LazySalesman(double d, std::vector<Location>::iterator it1, std::vector<Location>::iterator it2) : d_(d), Salesman(Location(0,0), it1, it2)
double visit()
double dist = 0;
dist = Salesman::visit();
dist += d_*ndest();
;
int main()
srand48(time(NULL));
Location start(0., 0.);
Location start2(1,1);
int cont = 0;
for(int i=0; i<3000; i++)
std::vector<Location> v;
for(int j=0; j<10; j++)
v.push_back(Location());
Salesman Willy(start, v.begin(), v.end());
if(Willy.visit() < 2.) cont++;
std::cout << "cont = " << cont << std::endl;
std::vector<Location> loc;
Location a(0.1, 0.1);
Location b(0.5, 0.1);
Location c(0.5, 0.5);
loc.push_back(a);
loc.push_back(b);
loc.push_back(c);
std::vector<Salesman*> vett;
vett.push_back(new Salesman(start2, loc.begin(), loc.end()));
vett.push_back(new LazySalesman(0.1, loc.begin(), loc.end()));
vett.push_back(new LazySalesman(0.5, loc.begin(), loc.end()));
for(auto el : vett)
std::cout << el->visit() << std::endl;
delete el;
c++ inheritance vectors constructor
add a comment |Â
up vote
3
down vote
favorite
I've written a program following the instructions of an exam paper. There are no solutions available so I would appreciate a feedback. I'm concerned with main
in particular (I've already posted a similar question here). I've tried to solve the problem as I've seen it's done in other solutions made available by our teacher. Also the constructors made me think a lot.
I was asked to make a program to represent destinations in a square [0,1]x[0,1], a salesman that has to go in some destinations in that square and another salesman inheriting from the former but with slightly different habits.
#include <iostream>
#include <vector>
#include <set>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstdlib>
class Location
private:
double x_, y_;
public:
Location(double x, double y) : x_(x), y_(y)
Location()
x_ = drand48();
y_ = drand48();
Location(const Location & L) : x_(L.x_), y_(L.y_)
double getx() return x_;
bool operator<(const Location & L) return x_ < L.x_;
double distance(const Location & L)
return std::sqrt(std::pow(x_ - L.x_, 2) + std::pow(y_ - L.y_, 2));
;
class Salesman
private:
Location start_;
protected:
std::vector<Location> tobevisited_;
public:
Salesman(const Location & start, std::vector<Location>::iterator it1, std::vector<Location>::iterator it2) : start_(start), tobevisited_(it1, it2)
int ndest() return tobevisited_.size();
virtual double visit()
double dist = 0;
sort(tobevisited_.begin(), tobevisited_.end());
dist = (*(tobevisited_.begin())).distance(start_);
for(std::vector<Location>::iterator it = tobevisited_.begin()+1; it != tobevisited_.end(); it++)
dist += (*(it)).distance(*(it-1));
return dist;
;
class LazySalesman : public Salesman
private:
double d_;
public:
LazySalesman(double d, std::vector<Location>::iterator it1, std::vector<Location>::iterator it2) : d_(d), Salesman(Location(0,0), it1, it2)
double visit()
double dist = 0;
dist = Salesman::visit();
dist += d_*ndest();
;
int main()
srand48(time(NULL));
Location start(0., 0.);
Location start2(1,1);
int cont = 0;
for(int i=0; i<3000; i++)
std::vector<Location> v;
for(int j=0; j<10; j++)
v.push_back(Location());
Salesman Willy(start, v.begin(), v.end());
if(Willy.visit() < 2.) cont++;
std::cout << "cont = " << cont << std::endl;
std::vector<Location> loc;
Location a(0.1, 0.1);
Location b(0.5, 0.1);
Location c(0.5, 0.5);
loc.push_back(a);
loc.push_back(b);
loc.push_back(c);
std::vector<Salesman*> vett;
vett.push_back(new Salesman(start2, loc.begin(), loc.end()));
vett.push_back(new LazySalesman(0.1, loc.begin(), loc.end()));
vett.push_back(new LazySalesman(0.5, loc.begin(), loc.end()));
for(auto el : vett)
std::cout << el->visit() << std::endl;
delete el;
c++ inheritance vectors constructor
add a comment |Â
up vote
3
down vote
favorite
up vote
3
down vote
favorite
I've written a program following the instructions of an exam paper. There are no solutions available so I would appreciate a feedback. I'm concerned with main
in particular (I've already posted a similar question here). I've tried to solve the problem as I've seen it's done in other solutions made available by our teacher. Also the constructors made me think a lot.
I was asked to make a program to represent destinations in a square [0,1]x[0,1], a salesman that has to go in some destinations in that square and another salesman inheriting from the former but with slightly different habits.
#include <iostream>
#include <vector>
#include <set>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstdlib>
class Location
private:
double x_, y_;
public:
Location(double x, double y) : x_(x), y_(y)
Location()
x_ = drand48();
y_ = drand48();
Location(const Location & L) : x_(L.x_), y_(L.y_)
double getx() return x_;
bool operator<(const Location & L) return x_ < L.x_;
double distance(const Location & L)
return std::sqrt(std::pow(x_ - L.x_, 2) + std::pow(y_ - L.y_, 2));
;
class Salesman
private:
Location start_;
protected:
std::vector<Location> tobevisited_;
public:
Salesman(const Location & start, std::vector<Location>::iterator it1, std::vector<Location>::iterator it2) : start_(start), tobevisited_(it1, it2)
int ndest() return tobevisited_.size();
virtual double visit()
double dist = 0;
sort(tobevisited_.begin(), tobevisited_.end());
dist = (*(tobevisited_.begin())).distance(start_);
for(std::vector<Location>::iterator it = tobevisited_.begin()+1; it != tobevisited_.end(); it++)
dist += (*(it)).distance(*(it-1));
return dist;
;
class LazySalesman : public Salesman
private:
double d_;
public:
LazySalesman(double d, std::vector<Location>::iterator it1, std::vector<Location>::iterator it2) : d_(d), Salesman(Location(0,0), it1, it2)
double visit()
double dist = 0;
dist = Salesman::visit();
dist += d_*ndest();
;
int main()
srand48(time(NULL));
Location start(0., 0.);
Location start2(1,1);
int cont = 0;
for(int i=0; i<3000; i++)
std::vector<Location> v;
for(int j=0; j<10; j++)
v.push_back(Location());
Salesman Willy(start, v.begin(), v.end());
if(Willy.visit() < 2.) cont++;
std::cout << "cont = " << cont << std::endl;
std::vector<Location> loc;
Location a(0.1, 0.1);
Location b(0.5, 0.1);
Location c(0.5, 0.5);
loc.push_back(a);
loc.push_back(b);
loc.push_back(c);
std::vector<Salesman*> vett;
vett.push_back(new Salesman(start2, loc.begin(), loc.end()));
vett.push_back(new LazySalesman(0.1, loc.begin(), loc.end()));
vett.push_back(new LazySalesman(0.5, loc.begin(), loc.end()));
for(auto el : vett)
std::cout << el->visit() << std::endl;
delete el;
c++ inheritance vectors constructor
I've written a program following the instructions of an exam paper. There are no solutions available so I would appreciate a feedback. I'm concerned with main
in particular (I've already posted a similar question here). I've tried to solve the problem as I've seen it's done in other solutions made available by our teacher. Also the constructors made me think a lot.
I was asked to make a program to represent destinations in a square [0,1]x[0,1], a salesman that has to go in some destinations in that square and another salesman inheriting from the former but with slightly different habits.
#include <iostream>
#include <vector>
#include <set>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstdlib>
class Location
private:
double x_, y_;
public:
Location(double x, double y) : x_(x), y_(y)
Location()
x_ = drand48();
y_ = drand48();
Location(const Location & L) : x_(L.x_), y_(L.y_)
double getx() return x_;
bool operator<(const Location & L) return x_ < L.x_;
double distance(const Location & L)
return std::sqrt(std::pow(x_ - L.x_, 2) + std::pow(y_ - L.y_, 2));
;
class Salesman
private:
Location start_;
protected:
std::vector<Location> tobevisited_;
public:
Salesman(const Location & start, std::vector<Location>::iterator it1, std::vector<Location>::iterator it2) : start_(start), tobevisited_(it1, it2)
int ndest() return tobevisited_.size();
virtual double visit()
double dist = 0;
sort(tobevisited_.begin(), tobevisited_.end());
dist = (*(tobevisited_.begin())).distance(start_);
for(std::vector<Location>::iterator it = tobevisited_.begin()+1; it != tobevisited_.end(); it++)
dist += (*(it)).distance(*(it-1));
return dist;
;
class LazySalesman : public Salesman
private:
double d_;
public:
LazySalesman(double d, std::vector<Location>::iterator it1, std::vector<Location>::iterator it2) : d_(d), Salesman(Location(0,0), it1, it2)
double visit()
double dist = 0;
dist = Salesman::visit();
dist += d_*ndest();
;
int main()
srand48(time(NULL));
Location start(0., 0.);
Location start2(1,1);
int cont = 0;
for(int i=0; i<3000; i++)
std::vector<Location> v;
for(int j=0; j<10; j++)
v.push_back(Location());
Salesman Willy(start, v.begin(), v.end());
if(Willy.visit() < 2.) cont++;
std::cout << "cont = " << cont << std::endl;
std::vector<Location> loc;
Location a(0.1, 0.1);
Location b(0.5, 0.1);
Location c(0.5, 0.5);
loc.push_back(a);
loc.push_back(b);
loc.push_back(c);
std::vector<Salesman*> vett;
vett.push_back(new Salesman(start2, loc.begin(), loc.end()));
vett.push_back(new LazySalesman(0.1, loc.begin(), loc.end()));
vett.push_back(new LazySalesman(0.5, loc.begin(), loc.end()));
for(auto el : vett)
std::cout << el->visit() << std::endl;
delete el;
c++ inheritance vectors constructor
edited May 2 at 0:37
Jamalâ¦
30.1k11114225
30.1k11114225
asked May 1 at 10:36
Gitana
1099
1099
add a comment |Â
add a comment |Â
1 Answer
1
active
oldest
votes
up vote
4
down vote
accepted
Tell your instructor to become familiar with the Standard Guidelines. You can find presentations on youtube where Stroustrup introduces this as a keynote speech, and many others speaking on them since.
DonâÂÂt use naked new
(and delete
). Make your vector of unique_ptr
instead.
The srand48 is not a standard function. And the old C rand/srand are infamous for poor quality random numbers. See the <random>
header file.
Why does one location use 0.
(funny way to write 0.0
, a double
) and the other use 1
as an int
?
You donâÂÂt need to put private:
at the top of the class; that is assumed.
Does visit
modify the object? You did not make it const
. Also, use the override
keyword in the derived version! That is very important in real code for maintainability as well as error checking.
for(int j=0; j<10; j++) v.push_back(Location());
Did you know that vector elements are always initialized? And what will it use do you suppose? The default constructor of the element, of course!
So just write: v.resize(10+v.size())
to add 10 default locations to the end.
Location a(0.1, 0.1);
Use uniform initialization syntax.
Location a0.1, 0.1;
Thou hast scribed an olde dialect. YouâÂÂre using the ranged for
loop so your textbook must be written after 2011; perhaps it is just a slightly updated lesson plan from 1998?
Location()
x_ = drand48();
y_ = drand48();
A random-initialized location might be handy for this specific program, but itâÂÂs sufficiently bizzare that it hinders the understanding of the code. Make a function to return a random location instead!
double getx() return x_;
bool operator<(const Location & L) return x_ < L.x_;
You are definitly missing const
on your member functions.
Writing good relational operators is a whole lesson and not the point here â this is probably fine for the class as it stands, but reviewers will wonder why you didnâÂÂt make it a non-member and supply all the relational and equality operators.
Since the (partial) ordering exists specifically for your algorithm, you might want to make it a named function instead. Consider the future maintainer that writes a test using >
and then has to figure out why it didnâÂÂt compile, and of course documenting that less means East and is not a complete ordering.
double distance(const Location & L) {
return std::sqrt(std::pow(x_ - L.x_, 2) + std::pow(y_ - L.y_, 2));
Besides being const
, just call std::hypot
. It will be faster and more accurate.
Salesman(const Location & start, std::vector<Location>::iterator it1, std::vector<Location>::iterator it2)
: start_(start), tobevisited_(it1, it2)
Very interesting that you allow salesman to be initialized with a segment of a larger vector. Is that a use case you anticipate (e.g. a huge list divided up among several salesmen)?
ItâÂÂs enlightened but only part way to what we expect: it is limited to segments of another vector, and canâÂÂt take begin/end iterators to locations in general (anything that can be iterated).
Also, you should be using the const_iterator
.
Here is the simple/direct way to take that information in the constructor.
â®
Location start_;
std::vector<Location> tobevisited_;
public:
Salesman (start, std::vector<Location> locations)
: start_start, tobevisited_std::move(locations)
Get a post-it note and write using a fat marker, âÂÂCan it be const
?âÂÂ. Stick that on the edge of your monitor.
thank you for your insights, I hadn't thought about the uselessness of the nested for! I'll try to renew my dialect. I gave to the constructor of salesman iterators of a vector because it seemed to me the easiest way to define his protected member
â Gitana
May 1 at 13:55
Just pass the vector as a single parameter. (In fact, this will be a âÂÂsinkâ parameter so pass by value andmove
in the initialization list.)Salesman Willystart, v;
â JDà Âugosz
May 1 at 18:35
add a comment |Â
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
4
down vote
accepted
Tell your instructor to become familiar with the Standard Guidelines. You can find presentations on youtube where Stroustrup introduces this as a keynote speech, and many others speaking on them since.
DonâÂÂt use naked new
(and delete
). Make your vector of unique_ptr
instead.
The srand48 is not a standard function. And the old C rand/srand are infamous for poor quality random numbers. See the <random>
header file.
Why does one location use 0.
(funny way to write 0.0
, a double
) and the other use 1
as an int
?
You donâÂÂt need to put private:
at the top of the class; that is assumed.
Does visit
modify the object? You did not make it const
. Also, use the override
keyword in the derived version! That is very important in real code for maintainability as well as error checking.
for(int j=0; j<10; j++) v.push_back(Location());
Did you know that vector elements are always initialized? And what will it use do you suppose? The default constructor of the element, of course!
So just write: v.resize(10+v.size())
to add 10 default locations to the end.
Location a(0.1, 0.1);
Use uniform initialization syntax.
Location a0.1, 0.1;
Thou hast scribed an olde dialect. YouâÂÂre using the ranged for
loop so your textbook must be written after 2011; perhaps it is just a slightly updated lesson plan from 1998?
Location()
x_ = drand48();
y_ = drand48();
A random-initialized location might be handy for this specific program, but itâÂÂs sufficiently bizzare that it hinders the understanding of the code. Make a function to return a random location instead!
double getx() return x_;
bool operator<(const Location & L) return x_ < L.x_;
You are definitly missing const
on your member functions.
Writing good relational operators is a whole lesson and not the point here â this is probably fine for the class as it stands, but reviewers will wonder why you didnâÂÂt make it a non-member and supply all the relational and equality operators.
Since the (partial) ordering exists specifically for your algorithm, you might want to make it a named function instead. Consider the future maintainer that writes a test using >
and then has to figure out why it didnâÂÂt compile, and of course documenting that less means East and is not a complete ordering.
double distance(const Location & L) {
return std::sqrt(std::pow(x_ - L.x_, 2) + std::pow(y_ - L.y_, 2));
Besides being const
, just call std::hypot
. It will be faster and more accurate.
Salesman(const Location & start, std::vector<Location>::iterator it1, std::vector<Location>::iterator it2)
: start_(start), tobevisited_(it1, it2)
Very interesting that you allow salesman to be initialized with a segment of a larger vector. Is that a use case you anticipate (e.g. a huge list divided up among several salesmen)?
ItâÂÂs enlightened but only part way to what we expect: it is limited to segments of another vector, and canâÂÂt take begin/end iterators to locations in general (anything that can be iterated).
Also, you should be using the const_iterator
.
Here is the simple/direct way to take that information in the constructor.
â®
Location start_;
std::vector<Location> tobevisited_;
public:
Salesman (start, std::vector<Location> locations)
: start_start, tobevisited_std::move(locations)
Get a post-it note and write using a fat marker, âÂÂCan it be const
?âÂÂ. Stick that on the edge of your monitor.
thank you for your insights, I hadn't thought about the uselessness of the nested for! I'll try to renew my dialect. I gave to the constructor of salesman iterators of a vector because it seemed to me the easiest way to define his protected member
â Gitana
May 1 at 13:55
Just pass the vector as a single parameter. (In fact, this will be a âÂÂsinkâ parameter so pass by value andmove
in the initialization list.)Salesman Willystart, v;
â JDà Âugosz
May 1 at 18:35
add a comment |Â
up vote
4
down vote
accepted
Tell your instructor to become familiar with the Standard Guidelines. You can find presentations on youtube where Stroustrup introduces this as a keynote speech, and many others speaking on them since.
DonâÂÂt use naked new
(and delete
). Make your vector of unique_ptr
instead.
The srand48 is not a standard function. And the old C rand/srand are infamous for poor quality random numbers. See the <random>
header file.
Why does one location use 0.
(funny way to write 0.0
, a double
) and the other use 1
as an int
?
You donâÂÂt need to put private:
at the top of the class; that is assumed.
Does visit
modify the object? You did not make it const
. Also, use the override
keyword in the derived version! That is very important in real code for maintainability as well as error checking.
for(int j=0; j<10; j++) v.push_back(Location());
Did you know that vector elements are always initialized? And what will it use do you suppose? The default constructor of the element, of course!
So just write: v.resize(10+v.size())
to add 10 default locations to the end.
Location a(0.1, 0.1);
Use uniform initialization syntax.
Location a0.1, 0.1;
Thou hast scribed an olde dialect. YouâÂÂre using the ranged for
loop so your textbook must be written after 2011; perhaps it is just a slightly updated lesson plan from 1998?
Location()
x_ = drand48();
y_ = drand48();
A random-initialized location might be handy for this specific program, but itâÂÂs sufficiently bizzare that it hinders the understanding of the code. Make a function to return a random location instead!
double getx() return x_;
bool operator<(const Location & L) return x_ < L.x_;
You are definitly missing const
on your member functions.
Writing good relational operators is a whole lesson and not the point here â this is probably fine for the class as it stands, but reviewers will wonder why you didnâÂÂt make it a non-member and supply all the relational and equality operators.
Since the (partial) ordering exists specifically for your algorithm, you might want to make it a named function instead. Consider the future maintainer that writes a test using >
and then has to figure out why it didnâÂÂt compile, and of course documenting that less means East and is not a complete ordering.
double distance(const Location & L) {
return std::sqrt(std::pow(x_ - L.x_, 2) + std::pow(y_ - L.y_, 2));
Besides being const
, just call std::hypot
. It will be faster and more accurate.
Salesman(const Location & start, std::vector<Location>::iterator it1, std::vector<Location>::iterator it2)
: start_(start), tobevisited_(it1, it2)
Very interesting that you allow salesman to be initialized with a segment of a larger vector. Is that a use case you anticipate (e.g. a huge list divided up among several salesmen)?
ItâÂÂs enlightened but only part way to what we expect: it is limited to segments of another vector, and canâÂÂt take begin/end iterators to locations in general (anything that can be iterated).
Also, you should be using the const_iterator
.
Here is the simple/direct way to take that information in the constructor.
â®
Location start_;
std::vector<Location> tobevisited_;
public:
Salesman (start, std::vector<Location> locations)
: start_start, tobevisited_std::move(locations)
Get a post-it note and write using a fat marker, âÂÂCan it be const
?âÂÂ. Stick that on the edge of your monitor.
thank you for your insights, I hadn't thought about the uselessness of the nested for! I'll try to renew my dialect. I gave to the constructor of salesman iterators of a vector because it seemed to me the easiest way to define his protected member
â Gitana
May 1 at 13:55
Just pass the vector as a single parameter. (In fact, this will be a âÂÂsinkâ parameter so pass by value andmove
in the initialization list.)Salesman Willystart, v;
â JDà Âugosz
May 1 at 18:35
add a comment |Â
up vote
4
down vote
accepted
up vote
4
down vote
accepted
Tell your instructor to become familiar with the Standard Guidelines. You can find presentations on youtube where Stroustrup introduces this as a keynote speech, and many others speaking on them since.
DonâÂÂt use naked new
(and delete
). Make your vector of unique_ptr
instead.
The srand48 is not a standard function. And the old C rand/srand are infamous for poor quality random numbers. See the <random>
header file.
Why does one location use 0.
(funny way to write 0.0
, a double
) and the other use 1
as an int
?
You donâÂÂt need to put private:
at the top of the class; that is assumed.
Does visit
modify the object? You did not make it const
. Also, use the override
keyword in the derived version! That is very important in real code for maintainability as well as error checking.
for(int j=0; j<10; j++) v.push_back(Location());
Did you know that vector elements are always initialized? And what will it use do you suppose? The default constructor of the element, of course!
So just write: v.resize(10+v.size())
to add 10 default locations to the end.
Location a(0.1, 0.1);
Use uniform initialization syntax.
Location a0.1, 0.1;
Thou hast scribed an olde dialect. YouâÂÂre using the ranged for
loop so your textbook must be written after 2011; perhaps it is just a slightly updated lesson plan from 1998?
Location()
x_ = drand48();
y_ = drand48();
A random-initialized location might be handy for this specific program, but itâÂÂs sufficiently bizzare that it hinders the understanding of the code. Make a function to return a random location instead!
double getx() return x_;
bool operator<(const Location & L) return x_ < L.x_;
You are definitly missing const
on your member functions.
Writing good relational operators is a whole lesson and not the point here â this is probably fine for the class as it stands, but reviewers will wonder why you didnâÂÂt make it a non-member and supply all the relational and equality operators.
Since the (partial) ordering exists specifically for your algorithm, you might want to make it a named function instead. Consider the future maintainer that writes a test using >
and then has to figure out why it didnâÂÂt compile, and of course documenting that less means East and is not a complete ordering.
double distance(const Location & L) {
return std::sqrt(std::pow(x_ - L.x_, 2) + std::pow(y_ - L.y_, 2));
Besides being const
, just call std::hypot
. It will be faster and more accurate.
Salesman(const Location & start, std::vector<Location>::iterator it1, std::vector<Location>::iterator it2)
: start_(start), tobevisited_(it1, it2)
Very interesting that you allow salesman to be initialized with a segment of a larger vector. Is that a use case you anticipate (e.g. a huge list divided up among several salesmen)?
ItâÂÂs enlightened but only part way to what we expect: it is limited to segments of another vector, and canâÂÂt take begin/end iterators to locations in general (anything that can be iterated).
Also, you should be using the const_iterator
.
Here is the simple/direct way to take that information in the constructor.
â®
Location start_;
std::vector<Location> tobevisited_;
public:
Salesman (start, std::vector<Location> locations)
: start_start, tobevisited_std::move(locations)
Get a post-it note and write using a fat marker, âÂÂCan it be const
?âÂÂ. Stick that on the edge of your monitor.
Tell your instructor to become familiar with the Standard Guidelines. You can find presentations on youtube where Stroustrup introduces this as a keynote speech, and many others speaking on them since.
DonâÂÂt use naked new
(and delete
). Make your vector of unique_ptr
instead.
The srand48 is not a standard function. And the old C rand/srand are infamous for poor quality random numbers. See the <random>
header file.
Why does one location use 0.
(funny way to write 0.0
, a double
) and the other use 1
as an int
?
You donâÂÂt need to put private:
at the top of the class; that is assumed.
Does visit
modify the object? You did not make it const
. Also, use the override
keyword in the derived version! That is very important in real code for maintainability as well as error checking.
for(int j=0; j<10; j++) v.push_back(Location());
Did you know that vector elements are always initialized? And what will it use do you suppose? The default constructor of the element, of course!
So just write: v.resize(10+v.size())
to add 10 default locations to the end.
Location a(0.1, 0.1);
Use uniform initialization syntax.
Location a0.1, 0.1;
Thou hast scribed an olde dialect. YouâÂÂre using the ranged for
loop so your textbook must be written after 2011; perhaps it is just a slightly updated lesson plan from 1998?
Location()
x_ = drand48();
y_ = drand48();
A random-initialized location might be handy for this specific program, but itâÂÂs sufficiently bizzare that it hinders the understanding of the code. Make a function to return a random location instead!
double getx() return x_;
bool operator<(const Location & L) return x_ < L.x_;
You are definitly missing const
on your member functions.
Writing good relational operators is a whole lesson and not the point here â this is probably fine for the class as it stands, but reviewers will wonder why you didnâÂÂt make it a non-member and supply all the relational and equality operators.
Since the (partial) ordering exists specifically for your algorithm, you might want to make it a named function instead. Consider the future maintainer that writes a test using >
and then has to figure out why it didnâÂÂt compile, and of course documenting that less means East and is not a complete ordering.
double distance(const Location & L) {
return std::sqrt(std::pow(x_ - L.x_, 2) + std::pow(y_ - L.y_, 2));
Besides being const
, just call std::hypot
. It will be faster and more accurate.
Salesman(const Location & start, std::vector<Location>::iterator it1, std::vector<Location>::iterator it2)
: start_(start), tobevisited_(it1, it2)
Very interesting that you allow salesman to be initialized with a segment of a larger vector. Is that a use case you anticipate (e.g. a huge list divided up among several salesmen)?
ItâÂÂs enlightened but only part way to what we expect: it is limited to segments of another vector, and canâÂÂt take begin/end iterators to locations in general (anything that can be iterated).
Also, you should be using the const_iterator
.
Here is the simple/direct way to take that information in the constructor.
â®
Location start_;
std::vector<Location> tobevisited_;
public:
Salesman (start, std::vector<Location> locations)
: start_start, tobevisited_std::move(locations)
Get a post-it note and write using a fat marker, âÂÂCan it be const
?âÂÂ. Stick that on the edge of your monitor.
edited May 1 at 20:19
answered May 1 at 12:24
JDÃ Âugosz
5,047731
5,047731
thank you for your insights, I hadn't thought about the uselessness of the nested for! I'll try to renew my dialect. I gave to the constructor of salesman iterators of a vector because it seemed to me the easiest way to define his protected member
â Gitana
May 1 at 13:55
Just pass the vector as a single parameter. (In fact, this will be a âÂÂsinkâ parameter so pass by value andmove
in the initialization list.)Salesman Willystart, v;
â JDà Âugosz
May 1 at 18:35
add a comment |Â
thank you for your insights, I hadn't thought about the uselessness of the nested for! I'll try to renew my dialect. I gave to the constructor of salesman iterators of a vector because it seemed to me the easiest way to define his protected member
â Gitana
May 1 at 13:55
Just pass the vector as a single parameter. (In fact, this will be a âÂÂsinkâ parameter so pass by value andmove
in the initialization list.)Salesman Willystart, v;
â JDà Âugosz
May 1 at 18:35
thank you for your insights, I hadn't thought about the uselessness of the nested for! I'll try to renew my dialect. I gave to the constructor of salesman iterators of a vector because it seemed to me the easiest way to define his protected member
â Gitana
May 1 at 13:55
thank you for your insights, I hadn't thought about the uselessness of the nested for! I'll try to renew my dialect. I gave to the constructor of salesman iterators of a vector because it seemed to me the easiest way to define his protected member
â Gitana
May 1 at 13:55
Just pass the vector as a single parameter. (In fact, this will be a âÂÂsinkâ parameter so pass by value and
move
in the initialization list.) Salesman Willystart, v;
â JDà Âugosz
May 1 at 18:35
Just pass the vector as a single parameter. (In fact, this will be a âÂÂsinkâ parameter so pass by value and
move
in the initialization list.) Salesman Willystart, v;
â JDà Âugosz
May 1 at 18:35
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f193343%2frepresenting-destinations-in-a-square%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password