Iterator in order of magnitude of permutation

I have a simple structure to swap:

struct Permutation { vector<string> items; // ["val_0", "val_1", "val_2", "val_3", "val_4"] vector<short> permutationValue; // Let say value is [4, 2, 0, 1, 3] } 

I want to be able to use it in a range loop like

 for(string item: permutation){ { cout << item << endl; } 

The end of the expected exit should be:

 val_4 val_2 val_0 val_1 val_3 

What methods should be implemented in the Permutation class to achieve it?

+6
source share
2 answers

You will need to do a little work. You need to implement your own iterator class and begin() and end() :

 struct Permutation { std::vector<std::string> items; std::vector<short> permutationValue; class iterator; iterator begin(); iterator end(); }; 

Your iterator class will be a random access iterator:

 #include <iterator> class Permutation::iterator : public std::iterator<std::random_access_iterator_tag, std::string> { }; 

It is important to inherit from std::iterator so that your custom iterator works correctly with <algorithm> .

There are several possible ways to implement an iterator. But the general idea is that your iterator will save a pointer to its permutation object and the current index position in its private members of the class:

 private: Permutation *p; size_t pos; 

Its operator* obvious:

 public: std::string &operator*() const { return p->items[p->permutationValue[pos]]; } 

You will need to implement all the other iterator operators that increase / decrease the progress of the random access iterator, the operators ++ , -- , + , - , += , -= , just adding or subtracting pos .

You also need to implement all the comparison operators for your iterator class: < , > , = != , <= And >= , just by comparing pos .

These bits will be a little tedious, but inevitable.

Now all you have to do is implement begin() and end() by creating this instance of the iterator, setting the initial pos to 0 or items.size(); . Everything is ready. Now you can use range iteration.

For additional credit, you can also implement const_iterator .

In conclusion: it will be a bit of work, but it is not very difficult.

+5
source

This is not complete code for forward / reverse / random access iterators, but it is a good place to run:

 struct perm_iter { const vector<short>& perm_; const vector<string>& items_; int idx_ {0}; perm_iter(int idx, const vector<short>& perm, const vector<string>& items) : idx_(idx) , perm_(perm) , items_(items) {} perm_iter& operator++() { idx_++; return *this; } bool operator!=(const perm_iter& i) const { return idx_ != i.idx_; } string operator*() { return items_[perm_[idx_]]; } }; struct Permutation { /* ... */ perm_iter begin() { return perm_iter(0, permutationValue, items); } perm_iter end() { return perm_iter(items.size(), permutationValue, items); } }; //usage: Permutation p; for (string s : p) cout << s << endl; 
0
source

Source: https://habr.com/ru/post/1012725/


All Articles