ordering a map

If I have 2 maps like ..
1
2
map <int, int> X;
map <int, int> Y;

.. and they holds coordinates for drawing something, like a house. The data looks like ..
1
2
3
4
5
6
7
8
X[0] = 15;
X[1] = 19;
X[2] = 32;
X[3] = 2;
Y[0] = 42;
Y[1] = 73;
Y[2] = 22;
Y[3] = 4;


I loop through them and draw lines from each to form a shape.

How is the best way to flip the shape vertically or horizontally ?

I am sure it's a simple algorithim, but I am drawing a blank.
First, you need the boundaries of the screen. Let's say it's xtotal=640 and ytotal=480.

For a horizontal mirror (<-- becomes -->) do x[i]=xtotal-x[i].
For a vertical mirror (v becomes ^) do y[i]=ytotal-y[i].
Doing both horizontal and vertical mirrors at the same time is the same as rotating 180°.

And don't use a map for that. Use a vector. Maps are used for different purposes (e.g. storing variables defined at run-time).
Thanks for the reply Helios.

I knew it was something simple like that.

Also, the data is read from a text file and the values are set at run time. I'm not sure why a map shouldn't be used in this case.
You *could* use a map, but if you access a variable that does not exist, then the map will create it for you...which could be a problem...you could either make two vectors:

1
2
vector <int> xcoord;
vector <int> ycoord;


Or use one vector:

 
vector < vector <int> > coords; //<-- Last spaces are IMPORTANT!! 


And access it like this:

coords.at(x).at(y) == 1;

Maps are used more for stuff like this (I think):

1
2
3
4
5
6
7
map <string, MyClass> MyClasses;
//add classes to MyClasses
if(MyClasses.find("MyClassName") != MyClasses.end()) {
    cout<<MyClasses["MyClassName"].somedata;
} else {
    cout<<"Class does not exist."<<endl;
}


So that you don't have to iterate through a very large vector until you find the right "name" or whatever you looking for.
Last edited on
If you make it multi-dimensional vector like that, is there a way to have seperate iterators ?
I'm not sure why a map shouldn't be used in this case.

The simple answer: prefer a std::vector whenever it suffices, and a std::list when you have many insertion/deletions "in the middle".
In this case, I would use a std::vector<std::pair<int, int> >

The somewhat more complicated answer: you have to access each element, one after another. If you use map::operator[], each call costs you O(log n) if n elements are being stored in the map, so doing it n times results in a total cost of O(n*log n). If you use a vector instead, the same thing can be done in O(n). You could use map's iterator, which provides a O(1) operator++, but still you have overhead due to the underlaying representation (in my STL implementation (g++/HP), that is a Red-Black-Tree).

If you make it multi-dimensional vector like that, is there a way to have seperate iterators ?

Yes, of course. The value type of the first iterator is then a std::vector<int>, which provides it's own iterator.
Last edited on
Ahh, thanks for the explanation guys.

I will switch it to a vector and read up on the differences.
firedraco is correct. That's what I meant by variables defined at run-time. Another name for maps is dictionary, because you look up a value assigned to a key, which is the exact behavior of variables.

However, that is not the way to face this problem. You're supposed to use a structure:
1
2
3
4
struct 2D_point{
	int x;
	int y;
};

And declare it like this: std::vector<2D_point> points

EDIT: Or you can use what exception posted there. I prefer the simpler solution, but you use the one you like the best.
Last edited on
Not really, no. The ycoord iterator would always be dependant on the xcoord iterator.

You can use integer indices to the same effect:
1
2
3
for (unsigned col = 0; col < coords.at(0).at(0).size(); col++)
for (unsigned row = 0; row < coords.at(0).size(); row++)
  cout << coords[row][col] << endl;

This, of course, assumes that all the rows have the same number of columns.
Topic archived. No new replies allowed.