How to rewrite this index way code using iterators.
This is a exercise on C++ Primer 5th. P112
I am asked to write the following code from using index to using iterator.
1 2 3 4 5 6
|
vector<unsigned> scores(11, 0);
unsigned grade;
while (cin >> grade) {
if (grade <= 100)
++scores[grade / 10];
}
|
It's aim is to cluster scores by 10. like I give 4, 5, 10, 99, then the scores vector would hold 2 1 0 0 0 0 0 0 1 0
std::advance is similar to it + n
or or it++
.
I think this exercise is awkward, too. I haven't find a way to realize it.
anyone help
Last edited on
is this ok?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
|
#include <string>
#include <iostream>
#include <cstdlib>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
vector<unsigned> scores(11, 0);
unsigned grade;
while (cin >> grade)
{
if (grade <= 100)
{
unsigned result = grade/10;
auto &vi = scores.begin() + result;
std::cout << "grade " << result << std::endl;
std::cout << "old value " << *vi << std::endl;
*vi+=1;
unsigned new_val = *vi;
std::cout << "iterator value " << new_val << std::endl;
}
else
{
break;
}
}
std::cout << std::endl;
std::cout << std::endl;
for (int i=0; i < scores.size(); i++)
{
std::cout << scores[i] << std::endl;
}
int x;
cin >> x;
return 0;
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
|
#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
int main()
{
std::vector< unsigned int > scores(11) ;
unsigned int grade ;
while( std::cin >> grade )
{
const auto n = std::min( grade, 100U ) / 10 ;
// option one: requires random access iterator
const auto iterb = scores.begin() ;
++iterb[n] ;
// option two: requires random access iterator
const auto itern = scores.begin() + n ;
++*itern ;
// option three: random access iterator is not required
auto iterf = scores.begin() ;
std::advance( iterf, n ) ;
++*iterf ;
}
}
|
thanks, ic now. I think this exercise is not that good, using iterator way is much more complex than using subscripts.
There's also
std::next(), which makes life a lot easier over
std::advance().
I notice that none of the given solutions behave like the original code snippet.
There
are other ways of thinking about it too... Given the original design this is definitely less efficient, but it is a valid transform:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
|
#include <algorithm>
#include <functional>
#include <iostream>
#include <iterator>
#include <numeric>
#include <set>
#include <vector>
using namespace std;
int main()
{
vector <unsigned> scores( 11, 0 );
{
multiset <unsigned> scoreset;
transform(
istream_iterator <unsigned> ( cin ),
istream_iterator <unsigned> (),
inserter( scoreset, scoreset.begin() ),
bind( divides <unsigned> (), placeholders::_1, 10 )
);
iota( scores.begin(), scores.end(), 0 );
for (unsigned& score: scores)
score = scoreset.count( score );
}
for (unsigned x: scores)
cout << x << " ";
}
|
Enjoy!
Topic archived. No new replies allowed.