Вопрос:

I want to reverse the values of map and print it using range based for loop.

c++ visual-studio

97 просмотра

3 ответа

1 Репутация автора

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 << ")" << "  ";
    }
Автор: Alok Kumar Источник Размещён: 13.04.2017 06:16

Ответы (3)


2 плюса

15542 Репутация автора

Решение

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).

Автор: BoBTFish Размещён: 13.04.2017 06:34

0 плюса

121 Репутация автора

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 Размещён: 13.04.2017 06:36

2 плюса

571 Репутация автора

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;
}
Автор: Liger Размещён: 13.04.2017 06:40
Вопросы из категории :
32x32