I was supposed to create a base class (P2D) that represents a point in two dimensions and a derivate class (P3D) that represents a point in three dimensions. In the first class I created a method this way:
virtual istream& set(istream&); //sets the values
istream& P2D::set(istream& in){
in >> x >> y;
return in;
}
In the second class, instead:
istream& set(istream&); //sets the values
istream& P3D::set(istream& in){
P2D::set(in);
in >> z;
return in;
}
In the main function i thought about putting all points (regardless of whether they are in two or three dimensions) in a vector, and then about setting all points in a while cycle somehow using the set method above.
Here is the piece of code in question:
vector<P2D*> points;
bool ans(true);
P2D* p;
while(ans){
cout << "Insert a point" << endl;
p->set();
points.push_back(p);
cout << "Do you want to insert another point? ";
cin >> ans;
}
I know this is wrong and i know why, but is there a chance to overcome that not using the dinamic memory? Am i forced to let the user choice if he wants to insert a two or a three dimension point?
This seems broken to me, as inheritance implies an 'is a' relation, and 3D point definitely is not a 2D point.
This reflects on your problem, as there is no elegant way to do it as you suggest. IMO, user has to decide whether to enter 2D or 3D point, but still it doesn't make sense to keep it as a collection of 2D points.
It all depends on what you intend to do later with points in the collection. Maybe you should have a Point type as parent of both 2D and 3D point, but it is hard to tell without bigger context.
Related
I am trying to read two polynomials from a text file in my c++ program and i have written the following code, my issue is that its only reading the first one and the second one is coming out as all zeroes?
Also im thinking its probably because idk how to stop reading the first poly because apparently you cannot write:
while(f!='=')
anyways heres the code:
....
int main()
{
poly *p1,*p2;
p1=NULL;
p2=NULL;
fstream f; //error: only reading first polynomial
f.open("input1.txt");
// string x1="4X7-2X6-1X3+4X2+3X0=0"; //these are the polynomials im trying to read
// string x2="2X6+3X2-2X0=0";
int c,e;
char b;
int x,i=0;
cout<<"Number of terms of poly 1: ";
cin>>x;
while(i<x)
{
f>>c>>b>>e;
cout<<c<<b<<e;
p1=p1->create(p1,c,b,e);
i++;
}
p1->display(p1);
cout<<"\nNumber of terms of poly 2: ";
cin>>x;
i=0;
while(i<x)
{
f<<endl;
f>>c>>b>>e;
cout<<c<<b<<e;
p2=p2->create(p2,c,b,e);
i++;
}
p1->display(p2);
poly *p3;
cout<<"\nThe addition of polynomials is:";
p3=p3->polyaddition(p1,p2);
p3->display(p3);
}
i wanted to read the polynomials without asking the number of elements on console. Any help would be appreciated. Thanks!
Most important thing to do: Write a function which reads just one monomial component - the next one on the input. Then invoke it repeatedly until you get to the end of the line.
Of course, before implementing the function, take the time to carefully consider what the signature of that function needs to be; and how a polynomial should be represented, when you don't know its degree in advance.
Notes:
You absolutely must take care to check for errors, like #user4581301 suggests - so that you don't end up in an infinite loop if the reading fails, or if you hit the end of the line in the middle of a supposed monomial etc.
Using this function, you'll get the added bonus of avoiding some of the code duplication you have now in reading the two polynomials. To avoid all of it, write a second function which reads an entire single polynomial.
I'm studying robotics at the university and I have to implement on my own SLAM algorithm. To do it I will use ROS, Gazebo and C++.
I have a doubt about what data structure I have to use to store the map (and what I'm going to store it, but this is another story).
I have thought to represent the map as a 2D grid and robot's start location is (0,0). But I don't know where exactly is the robot on the world that I have to map. It could be at the top left corner, at the middle of the world, or in any other unknonw location inside the world.
Each cell of the grid will be 1x1 meters. I will use a laser to know where are the obstacles. Using current robot's location, I will set to 1 on all the cells that represent an obstacle. For example, it laser detects an obstacle at 2 meters in front of the robot, I will set to 1 the cell at (0,2).
Using a vector, or a 2D matrix, here is a problem, because, vector and matrices indices start at 0, and there could be more room behind the robot to map. And that room will have an obstacle at (-1,-3).
On this data structure, I will need to store the cells that have an obstacle and the cells that I know they are free.
Which kind of data structure will I have to use?
UPDATE:
The process to store the map will be the following:
Robot starts at (0,0) cell. It will detect the obstacles and store them in the map.
Robot moves to (1,0) cell. And again, detect and store the obstacles in the map.
Continue moving to free cells and storing the obstacles it founds.
The robot will detect the obstacles that are in front of it and to the sides, but never behind it.
My problem comes when the robot detects an obstacle on a negative cell (like (0,-1). I don't know how to store that obstacle if I have previously stored only the obstacle on "positive" cells. So, maybe the "offset", it is not a solution here (or maybe I'm wrong).
This is where you can write a class to help you:
class RoboArray
{
constexpr int width_ = ...
constexpr int height_ = ...
Cell grid_[width_ * 2][height_ * 2];
...
public:
...
Cell get(int x, int y) // can make this use [x][y] notation with a helper class
{
return grid_[x + width_][y + height];
}
...
}
The options you have:
Have an offset. Simple and dirty. Your grid is 100x100 but stores -50,-50 to 50x50.
Have multiple offset'ed grids. When you go out of the grid allocate a new one beside it, with a different offset. A list or map of grids.
Have sparse structure. A set or map of coordinates.
Have an hierarchical structure. Your whole, say 50x50, grid is one cell in a grid at a higher level. Implement it with a linked list or something so when you move you build a tree of nest grids. Very efficient for memory and compute time, but much more complex to implement.
You can use a std::set to represent a grid layout by using a position class you create. It contains a x and y variable and can therefore be used to intuitively be used to find points inside the grid. You can also use a std::map if you want to store information about a certain location inside the grid.
Please don't forget to fulfill the C++ named requirements for set/map such as Compare if you don't want to provide a comparison operator externally.
example:
position.h
/* this class is used to store the position of things
* it is made up by a horizontal and a vertical position.
*/
class position{
private:
int32_t horizontalPosition;
int32_t verticalPosition;
public:
position::position(const int hPos = 0,const int vPos = 0) : horizontalPosition{hPos}, verticalPosition{vPos}{}
position::position(position& inputPos) : position(inputPos.getHorPos(),inputPos.getVerPos()){}
position::position(const position& inputPos) : position((inputPos).getHorPos(),(inputPos).getVerPos()){}
//insertion operator, it enables the use of cout on this object: cout << position(0,0) << endl;
friend std::ostream& operator<<(std::ostream& os, const position& dt){
os << dt.getHorPos() << "," << dt.getVerPos();
return os;
}
//greater than operator
bool operator>(const position& rh) const noexcept{
uint64_t ans1 = static_cast<uint64_t>(getVerPos()) | static_cast<uint64_t>(getHorPos())<<32;
uint64_t ans2 = static_cast<uint64_t>(rh.getVerPos()) | static_cast<uint64_t>(rh.getHorPos())<<32;
return(ans1 < ans2);
}
//lesser than operator
bool operator<(const position& rh) const noexcept{
uint64_t ans1 = static_cast<uint64_t>(getVerPos()) | static_cast<uint64_t>(getHorPos())<<32;
uint64_t ans2 = static_cast<uint64_t>(rh.getVerPos()) | static_cast<uint64_t>(rh.getHorPos())<<32;
return(ans1 > ans2);
}
//equal comparison operator
bool operator==(const position& inputPos)const noexcept {
return((getHorPos() == inputPos.getHorPos()) && (getVerPos() == inputPos.getVerPos()));
}
//not equal comparison operator
bool operator!=(const position& inputPos)const noexcept {
return((getHorPos() != inputPos.getHorPos()) || (getVerPos() != inputPos.getVerPos()));
}
void movNorth(void) noexcept{
++verticalPosition;
}
void movEast(void) noexcept{
++horizontalPosition;
}
void movSouth(void) noexcept{
--verticalPosition;
}
void movWest(void) noexcept{
--horizontalPosition;
}
position getNorthPosition(void)const noexcept{
position aPosition(*this);
aPosition.movNorth();
return(aPosition);
}
position getEastPosition(void)const noexcept{
position aPosition(*this);
aPosition.movEast();
return(aPosition);
}
position getSouthPosition(void)const noexcept{
position aPosition(*this);
aPosition.movSouth();
return(aPosition);
}
position getWestPosition(void)const noexcept{
position aPosition(*this);
aPosition.movWest();
return(aPosition);
}
int32_t getVerPos(void) const noexcept {
return(verticalPosition);
}
int32_t getHorPos(void) const noexcept {
return(horizontalPosition);
}
};
std::set<position> gridNoData;
std::map<position, bool> gridWithData;
gridNoData.insert(point(1,1));
gridWithData.insert(point(1,1),true);
gridNoData.insert(point(0,0));
gridWithData.insert(point(0,0),true);
auto search = gridNoData.find(point(0,0));
if (search != gridNoData.end()) {
std::cout << "0,0 exists" << '\n';
} else {
std::cout << "0,0 doesn't exist\n";
}
auto search = gridWithData.find(point(0,0));
if (search != gridWithData.end()) {
std::cout << "0,0 exists with value" << search->second << '\n';
} else {
std::cout << "0,0 doesn't exist\n";
}
The above class was used by me in a similar setting and we used a std::map defined as:
std::map<position,directionalState> exploredMap;
To store if we had found any walls at a certain position.
By using this std::map based method you avoid having to do math to know what offset you have to have inside an 2D array (or some structure like that). It also allows you to move freely as there is no chance that you'll travel outside of the predefined bounds you set at construction. This structure is also more space efficient against a 2D array as this structure only saves the areas where the robot has been. This is also a C++ way of doing things: relying on the STL instead of creating your own 2D map using C constructs.
With offset solution (translation of values by fixed formula (we called it "mapping function" in math class), like doing "+50" to all coordinates, i.e. [-30,-29] will become [+20,+21] and [0,0] will become [+50,+50] ) you still need to have idea what is your maximum size.
In case you want to be dynamic like std::vector<> going from 0 to some N (as much as free memory allows), you can create more complex mapping function, for example map(x) = x*2 when (0 <= x) and x*(-2)-1 when (x < 0) ... this way you can use standard std::vector and let it grow as needed by reaching new maximum coordinates.
With 2D grid vs std::vector this is a bit more complicated as vector of vectors is sometimes not the best idea from performance point of view, but as long as your code can prefer shortness and simplicity over performance, maybe you can use the same mapping for both coordinates and use vector of vectors (using reserve(..) on all of them with some reasonable default to avoid resizing of vectors in common use cases, like if you know the 100m x 100m area will be usual maximum, you can reserve everything to capacity 201 initially to avoid vector resizing for common situations, but it can still grow infinitely (until heap memory is exhausted) in less common situations.
You can also add another mapping function converting 2D coordinates to 1D and use single vector only, and if you want really complicate things, you can for example map those 2D into 0,1,2,... sequence growing from area around center outward to save memory usage for small areas... you will probably easily spend 2-4 weeks on debugging it, if you are kinda fresh to C++ development, and you don't use unit testing and TDD approach (I.e. just go by simple vector of vectors for a start, this paragraph is JFYI, how things can get complicated if you are trying to be too smart :) ).
Class robotArray
{
Int* left,right;
}
RobotArray::RobotArray ()
{
Int* a=new int [50][50];
Int* b=new int[50][50];
//left for the -ve space and right for the positive space with
0,0 of the two arrays removed
Left=a+1;
Right=b+1;
}
I think I see what you are after here: you don't know how big the space is, or even what the coordinates may be.
This is very general, but I would create a class that holds all of the data using vectors (another option -- vector of pairs, or vector of Eigen (the library) vectors). As you discover new regions, you'll add the coordinates and occupancy information to the Map (via AddObservation(), or something similar).
Later, you can determine the minimum and maximum x and y coordinates, and create the appropriate grid, if you like.
class RoboMap{
public:
vector<int> map_x_coord;
vector<int> map_y_coord;
vector<bool> occupancy;
RoboMap();
void AddObservation(int x, int y, bool in_out){
map_x_coord.push_back(x);
map_y_coord.push_back(y);
occupancy.push_back(in_out);
}
};
I am teaching myself c++ and while on the topic of pointers, I came across an exercise which wants me to define a function length() that receives the coordinates of a point P passed as a pointer, and computes the distance from the origin to the point P:
double length(Coord3D *p);
int main()
{
Coord3D pointP = {10, 20, 30};
cout << length(&pointP) << endl; // would print 37.4166
}
class Coord3D // Given this class which had variables x,y,z.
{
public:
double x;
double y;
double z;
};
I am confused as to what my next steps are for example I am thinking I should use pointers to create a variable p and set *p to the class.
Also I think the function at the very top should contain the formula which would be sqrt(pow(x,2)+pow(y,2)+pow(z,3)). If I am right then how can I implement the pointer properly and if I am wrong what I am I doing wrong and how can I fix it.
Please keep in mind this is my first time learning so I am trying my best.
The code that I wrote so far is :
#include<iostream>
#include<string>
#include<cmath>
using namespace std;
// Class
class Coord3D
{
public:
double x;
double y;
double z;
};
int p = Coord3D;
p*= Coord3D
// Function
double length(Coord3D *p)
{
double length = sqrt(pow(x,2)+pow(y,2)+pow(z,3));
cin>>x;
cin>>y;
cin>>z;
cout << length << endl;
}
// Main
int main()
{
Coord3D pointP = {10, 20, 30};
cout << length(&pointP) << endl; // would print 37.4166
}
Assuming the code works the output should a double that shows the distance from origin to point p.
Trouble writing a function is often a sign that more time needs to be spent designing the function. Let's start by moving your description of the function into the function's documentation:
// Receives the coordinates of a point P passed as a pointer, and
// computes the distance from the origin to the point P.
double length(Coord3D *p)
It's a start, but it combines three aspects of the function into one statement. Let's try breaking out 1) the function's purpose, 2) the function's input, 3) the function's output.
// Computes the distance from the origin to a point.
// Input: the point P passed as a pointer
// Output: the distance
double length(Coord3D *p)
You've already got an idea of how to accomplish the purpose (the call to the sqrt function), but you're not sure how to get values to that function. (Terminology note: "values", not "variables". The number 10 is a value, but it is not a variable. Variables have names, like "pointP". A single variable may hold one, many, or even no values, depending on its type.) So we should take a closer look at your function's input requirement.
// Input: the point P passed as a pointer
Well, that's not exactly right, is it? The inputs to a function come via parameters, but this function has no parameter named "P" (remember that case matters). In fact, the name "P" seems to refer to the variable in the main function. One important rule for writing good functions: keep it self-contained. In particular, we don't care what the caller calls things. So toss that name. We are only interested in "the point". (Which point? The one mentioned in the statement of the function's purpose. More complex cases would need to be more specific, but we're starting simple. You can work on more complex once you've got the simple down.)
Also, if the input parameter is a pointer, then it cannot be a point. This is where one of your programming skills comes in: translate the natural language description into more precise terms. A parameter cannot be "as a pointer"; either it is a pointer or it is not. Get rid of the wishy-washy and take a stand. We want a pointer!**
// Computes the distance from the origin to a point.
// Input: a pointer to the point
// Output: the distance (via a return statement)
double length(Coord3D *p)
Now hopefully things are becoming a bit clearer. This function needs to calculate the distance to the thing to which its parameter points (i.e. *p). It's not some "variable x" that you need to square, but the x-coordinate of *p. More precisely, you need to square the x field of the object to which p points, a.k.a. p->x. Similarly for y and z.
[Get rid of the statements between your class definition and your function definition -- they serve no purpose other than generating confusion. Get rid of the streaming operations (>> and <<) in your function -- that is not how this function is supposed to do its input/output. Input is via its parameter, and output is via its (currently missing) return statement.]
**Actually, we probably want a reference instead of a pointer, but that might be a future lesson.
Fixed version:
#include <iostream>
#include <cmath>
class Coord3D
{
public:
double x;
double y;
double z;
};
double length(const Coord3D& p)
{
return sqrt(pow(p.x, 2) + pow(p.y, 2) + pow(p.z, 2));
}
std::istream& operator >> (std::istream& is, Coord3D& p)
{
return is >> p.x >> p.y >> p.z;
}
int main()
{
Coord3D pointP = {10, 20, 30};
std::cout << length(pointP) << std::endl; // would print 37.4166
// And now from input:
std::cin >> pointP;
std::cout << length(pointP) << std::endl;
}
I apologize in advance for how poorly this question is asked, I'm really struggling here.
I am writing a class named Point in C++ with private members x and y, and member functions getX, getY, setX, setY, read and write. I have been able to do everything except read and write, as I am awful with input/output files. I have the following declaration for read and write:
void read(istream& ins);
void write(ostream& outs);
The RME is as follows for read:
* Requires: ins is in good state.
* Modifies: ins, x, y.
* Effects: Reads point in form (x,y)
and for write:
* Requires: outs is in good state.
* Modifies: outs.
* Effects: Writes point in form (x,y).
'read' takes ordered points like (1, 5), (2, 7), etc. from a given file "data1.txt" and extracts the x and y components (at least, I believe this is what it should do). I was provided with a test suite for read:
void test_point() {
Point pt1;
pt1.setX(15);
cout << "pt1 is: " << pt1 << endl;
ifstream input_file;
input_file.open("data1.txt");
pt1.read(input_file);
cout << "pt1 is: " << pt1 << endl;
return;}
I really have no idea how to write the read function. I have tried defining characters a, b, c, and integers u, v, and executing:
ins >> a >> u >> b >> v >> c;
but that didn't work. Could someone please help me see how to implement this?
Quite a few things missing from your question, that you will need such that the use of this class to be viable. For one, reading a file of ordered points should not be implemented as a member function. If anything, you could use a loop as such:
while(input_file) {
// set a point to have members x, y that were read from file
// store this point in a vector of points
}
Otherwise there is no reasonable way to store a bunch of points that you have read from a file.
Your idea for this solution within the read function should definitely work (assuming chars a, b, c, and ints u, v):
input_stream >> a >> u >> b >> v >> c;
In fact, with the format that you have given us (taking an ifstream as an argument), there really is no need for be much else in the read function, as it mutates the object and doesn't need to return anything. Your implementation is the simplest way to parse such "records" in a structured file.
After you read all these, set the x coordinate of the caller object to u, and the y to v. This should be a void function, does not need to return anything but should alter the Point object that it is being called for. This member function should be called on a temporary point object in the loop that I mentioned, then add that object to a vector of points as such:
vector<Point> points;
while(...) {
// declare Point
// initialize with values from read
points.push_back(//the point you just created);
}
If in fact you need to be able to read multiple points.
In summary, your read function needs:
To check that the ifstream is actually good first of all, which I didn't mention yet (but this is one of your requirements):
if (!input_file) { //however you want to handle this error }
The temporary char and int variables (serving as buffers) to read into (by the way, you can even read straight into x and y instead of reading into u and v then copying, just saying).
If you choose to not read straight into x and y, you must assign the u and v values to x and y. Now your object is complete.
As for the write function, instead of std::cout you will use the name of the ofstream that was passed as an argument to the write function, and write the records with the format that you have shown. This is (in essence) no different from printing to a console, except the output is on a text file.
Note: Make sure you understand the difference between iostream objects (istream, ostream) and fstream (ifstream, ofstream, fstream) objects, which are preferable in this case.
This is the class square and the main function.
const int max_size = 9;
class Square {
public:
void read(); //the square data is read
bool is_magic(); // determin if the given square is a magic square
private:
int sum_row(int i); // returns the row sum of the ith row
int sum_col(int i); // returns the col sum of the ith row
int sum_maindiag(); // returns the main the main diagonal sum
int sum_other(); // returns the non-main diagonal sum
int size;
int grid[max_size][max_size];
};
void main()
{
cout << "Magic Square Program" << endl << endl;
cout << "Enter a square of integers:" << endl;
Square s;
s.read();
if (s.is_magic()) cout << "That square is magic!" << endl;
else cout << "That square is not magic." << endl;
}
So basically you have to write and implement the Square class. The one that you've detailed has two public methods which means that those methods can be called anywhere. Therefore in your main you're calling the s.read() method and s.is_magic() to access the class. So you declare an instance of Square and call it s and then you use s.read() to call the read() method within s which is a instance of the class square.
You have a bunch of private functions in the square class to help write it. Private functions are functions that can only be called within that class. So start by making the read method within the square class. You should use the helper functions like sum_row() and sum_col() to help write your read function. Also the private class vars like size are able to be used across functions within the class.
If you have any questions leave a comment. But if you're trying to get out of writing the code yourself no one here is going to write it for you. By the way I've used methods/functions interchangeably here, you can look up what the difference is if you want.
A good way to go about software is in 4 phases: Requirements, Design, Coding, Testing.
Requirements. What is it that you actually want to do? In your case, check for Magic Squares.
Design. How do you want to do this? Plan your software before you write code. Write it out in plain English (or whatever language).
Coding. Now that you have a plan, write your code.
Testing. Test your software to make sure it does what you set out to do.
You can do this in small iterations, all at once, there's a lot of variations on how to go about this, but it's a good way to approach the task of writing a program.
In your case, you're up to phase 2. So take the time to think about what a Magic Square is, and think of how to go about checking for it. Then try to take your algorithm and write it into code.