0

I have done the programming but it is not reversing. I have used a different map to put the values in reverse order,but it still shows the same. My main question was to traverse backward and print the values using range based loop.

#include "stdafx.h"
#include <iostream>
#include<conio.h>
#include <stdio.h>
#include<vector>
#include<map>
#include<utility>
#include<set>
    map<int, int>m1;
        for (int i = 1; i <= 100; ++i)
        {
            m1.insert({ i,i });
        }

    for (const auto &y :m1)
    {
        cout <<"("<< y.first << "  "<<y.second << ")" <<"  " ;
    }
    cout << endl << endl;
    map<int, int>m2;
    map<int, int>::reverse_iterator iter;

    for (auto iter = m1.rbegin(); iter != m1.rend(); ++iter)
    {
        m2.insert({ iter->first,iter->second });

    }       
   for (const auto &y : m2)
    {
        cout << "(" << y.first << "  " << y.second << ")" << "  ";
    }
  • 2
    Remember that [`std::map`](http://en.cppreference.com/w/cpp/container/map) is *sorted by the key*. If you want another map to be reversed, you have to use reverse sorting for the key (and yes you can customize the sorting function used). – Some programmer dude Apr 13 '17 at 06:18
  • what if i have to print the values of map in reverse manner using range based loops without using another map – Alok Kumar Apr 13 '17 at 06:22
  • Then I would say that you're probably interpreting your requirement very narrowly. Why do you *need* to use the range-based `for` loop? – Some programmer dude Apr 13 '17 at 11:43

3 Answers3

2

As Some Programmer Dude pointed out, but for the completeness of my answer, a std::map is sorted on the key, no matter what order you insert the elements. One option would be to create a new map with the opposite sorting, but that doesn't seem to be what you really want.

It seems you know how about reverse iterators, but not how to get at them when using range-based for. Since it operates on a range, i.e. some type that provides begin and end iterators, you need to create some wrapper around your map that provides this.

Here's a general one I just put together than works in C++11. It won't cover every possible case, and can be made a bit neater in C++14, but it will work for you.

#include <iostream>
#include <iterator>

// The wrapper type that does reversal
template <typename Range>
class Reverser {
    Range& r_;
  public:
    using iterator_type = std::reverse_iterator<decltype(std::begin(r_))>;

    Reverser(Range& r) : r_(r) {}

    iterator_type begin() { return iterator_type(std::end(r_)); }
    iterator_type end()   { return iterator_type(std::begin(r_)); }
};

// Helper creation function
template <typename Range>
Reverser<Range> reverse(Range& r)
{
    return Reverser<Range>(r);
}

int main()
{
    int vals[] = {1, 2, 3, 4, 5};
    for (auto i : reverse(vals))
        std::cout << i << '\n';
}

This outputs:

$ ./reverse
5
4
3
2
1

(You may also find libraries that provide a similar adapter; Eric Niebler is working on a ranges library for The Standard.)


Also, please reconsider your use of what are often considered bad practices: using namespace std; and endl (those are links to explanations).

Community
  • 1
  • 1
BoBTFish
  • 19,167
  • 3
  • 49
  • 76
2

Here's an example of iterating backward through a std::map:

#include <iostream>
#include <map>
#include <string>

int main() {
  std::map<int, int> m;
  m[1] = 1;
  m[2] = 2;
  m[3] = 3;

  for (auto iter = m.rbegin(); iter != m.rend(); ++iter) {
     std::cout << iter->first << ": " << iter->second << std::endl;
  }
}

If you are pre-C++11, you'll just need to spell out auto, which is:

std::map<int, int>::reverse_iterator

If you're using boost, you can use a range-based for loop with a reverse adapter:

#include <boost/range/adaptor/reversed.hpp>

for (auto& iter : boost::adaptors::reverse(m)) {
  std::cout << iter.first << ": " << iter.second << std::endl;
}
CocoCrisp
  • 807
  • 1
  • 9
  • 26
0

If you only need to print the elements in the map in reverse order,you don't need another map for it,you can do this:

    std::map<int, int>::reverse_iterator iter;

    for (iter = m1.rbegin(); iter != m1.rend(); ++iter)
    {
        std::cout << "(" << iter->first << "  " << iter->second << ")" << "  ";
    }
Valgrind1691
  • 182
  • 1
  • 11