Let m
be a variable of type map<int,string>
. Given that
copy(x.begin(), x.end(), front_inserter(m))
compiles and executes correctly, what is the type of x
?
The copy inserts elements into m
, and for those insertions to be correct,
the type of the elements being inserted must be pair<int,string>
, the
type of the elements in m. The interators returned by x.begin()
and
x.end()
must refer to values of type pair<int,string>
, and because
any STL container supports begin()
and end()
, x
can have type
vector<pair<int,string> >
, list<pair<int,string> >
, or
map<int,string>
Except, maps don't support push_front()
, so the code given in the problem
does not compile. What I should have written was
copy(x.begin(), x.end(), inserter(m, m.begin()))
For the curious, here's the error message produced by g++ for the code given in
the problem:
/usr/local/lib/gcc-lib/sparc-sun-solaris2.8/2.95.3/../../../../include/g++-3/stl_iterator.h:
In method class front_insert_iterator<map<basic_string<char,
string_char_traits<char>, __default_alloc_template<false, 0> >, int,
less<basic_string<char, string_char_traits<char>,
__default_alloc_template<false, 0> > >, allocator<int> > > &
front_insert_iterator<map<basic_string<char, string_char_traits<char>,
__default_alloc_template<false, 0> >, int, less<basic_string<char,
string_char_traits<char>, __default_alloc_template<false, 0> > >,
allocator<int> > >::operator =(const pair<const basic_string<char,
string_char_traits<char>, __default_alloc_template<false, 0> >, int> &):
/usr/local/lib/gcc-lib/sparc-sun-solaris2.8/2.95.3/../../../../include/g++-3/stl_algobase.h:139:
instantiated from __copy<pair<basic_string<char, string_char_traits<char>,
__default_alloc_template<false, 0> >, int> *,
front_insert_iterator<map<basic_string<char, string_char_traits<char>,
__default_alloc_template<false, 0> >, int, less<basic_string<char,
string_char_traits<char>, __default_alloc_template<false, 0> > >,
allocator<int> > >, ptrdiff_t>(pair<basic_string<char,
string_char_traits<char>, __default_alloc_template<false, 0> >, int> *,
pair<basic_string<char, string_char_traits<char>,
__default_alloc_template<false, 0> >, int> *,
front_insert_iterator<map<basic_string<char, string_char_traits<char>,
__default_alloc_template<false, 0> >, int, less<basic_string<char,
string_char_traits<char>, __default_alloc_template<false, 0> > >,
allocator<int> > >, random_access_iterator_tag, ptrdiff_t *)
/usr/local/lib/gcc-lib/sparc-sun-solaris2.8/2.95.3/../../../../include/g++-3/stl_algobase.h:161:
instantiated from __copy_dispatch<pair<basic_string<char,
string_char_traits<char>, __default_alloc_template<false, 0> >, int> *,
front_insert_iterator<map<basic_string<char, string_char_traits<char>,
__default_alloc_template<false, 0> >, int, less<basic_string<char,
string_char_traits<char>, __default_alloc_template<false, 0> > >,
allocator<int> > >, __false_type>::copy(pair<basic_string<char,
string_char_traits<char>, __default_alloc_template<false, 0> >, int> *,
pair<basic_string<char, string_char_traits<char>,
__default_alloc_template<false, 0> >, int> *,
front_insert_iterator<map<basic_string<char, string_char_traits<char>,
__default_alloc_template<false, 0> >, int, less<basic_string<char,
string_char_traits<char>, __default_alloc_template<false, 0> > >,
allocator<int> > >)
/usr/local/lib/gcc-lib/sparc-sun-solaris2.8/2.95.3/../../../../include/g++-3/stl_algobase.h:188:
instantiated from copy<pair<basic_string<char, string_char_traits<char>,
__default_alloc_template<false, 0> >, int> *,
front_insert_iterator<map<basic_string<char, string_char_traits<char>,
__default_alloc_template<false, 0> >, int, less<basic_string<char,
string_char_traits<char>, __default_alloc_template<false, 0> > >,
allocator<int> > > >(pair<basic_string<char, string_char_traits<char>,
__default_alloc_template<false, 0> >, int> *, pair<basic_string<char,
string_char_traits<char>, __default_alloc_template<false, 0> >, int> *,
front_insert_iterator<map<basic_string<char, string_char_traits<char>,
__default_alloc_template<false, 0> >, int, less<basic_string<char,
string_char_traits<char>, __default_alloc_template<false, 0> > >,
allocator<int> > >) t.cc:10: instantiated from here
/usr/local/lib/gcc-lib/sparc-sun-solaris2.8/2.95.3/../../../../include/g++-3/stl_iterator.h:400:
no matching function for call to map<basic_string<char,
string_char_traits<char>, __default_alloc_template<false, 0> >, int,
less<basic_string<char, string_char_traits<char>,
__default_alloc_template<false, 0> > >, allocator<int> >::push_front (const
pair<const basic_string<char, string_char_traits<char>,
__default_alloc_template<false, 0> >, int> &)
CC wasn't much better with this error:
"/export/opt/forte/SUNWspro/WS6U2/include/CC/Cstd/./algorithm.cc",
line 427: Error: Cannot assign std::pair<std::basic_string<char,
std::char_traits<char>, std::allocator<char>>, int> to
std::front_insert_iterator<std::map<std::basic_string<char,
std::char_traits<char>, std::allocator<char>>, int,
std::less<std::basic_string<char, std::char_traits<char>,
std::allocator<char>>>, std::allocator<std::pair<const std::basic_string<char,
std::char_traits<char>, std::allocator<char>>, int>>>> without
"std::front_insert_iterator<std::map<std::basic_string<char,
std::char_traits<char>, std::allocator<char>>, int,
std::less<std::basic_string<char, std::char_traits<char>,
std::allocator<char>>>, std::allocator<std::pair<const std::basic_string<char,
std::char_traits<char>, std::allocator<char>>, int>>>>::operator=(const
std::front_insert_iterator<std::map<std::basic_string<char,
std::char_traits<char>, std::allocator<char>>, int,
std::less<std::basic_string<char, std::char_traits<char>,
std::allocator<char>>>, std::allocator<std::pair<const std::basic_string<char,
std::char_traits<char>, std::allocator<char>>, int>>>>&)";.
"t.cc", line 10: Where: While instantiating
"std::copy<std::pair<std::basic_string<char, std::char_traits<char>,
std::allocator<char>>, int>*,
std::front_insert_iterator<std::map<std::basic_string<char,
std::char_traits<char>, std::allocator<char>>, int,
std::less<std::basic_string<char, std::char_traits<char>,
std::allocator<char>>>, std::allocator<std::pair<const std::basic_string<char,
std::char_traits<char>, std::allocator<char>>,
int>>>>>(std::pair<std::basic_string<char, std::char_traits<char>,
std::allocator<char>>, int>*, std::pair<std::basic_string<char,
std::char_traits<char>, std::allocator<char>>, int>*,
std::front_insert_iterator<std::map<std::basic_string<char,
std::char_traits<char>, std::allocator<char>>, int,
std::less<std::basic_string<char, std::char_traits<char>,
std::allocator<char>>>, std::allocator<std::pair<const std::basic_string<char,
std::char_traits<char>, std::allocator<char>>, int>>>>)".
"t.cc", line 10: Where: Instantiated from non-template code.
1 Error(s) detected.
Give an example where it would be better to use a map with an integer key
rather than a vector. (Hint: "When the data needs to be sorted." is
not a correct answer.)
If the distance between successive indicies refering to non-default values is
large, using a map instead of a vector would save space. For example, storing
the set of pairs
{ (0, 0), (10, 1), (100, 2), (1000, 3) }
would take four elements (or so) in a map and 1001 elements in a vector.
Provide an upper-bound asymptotic estimate for the run-time of the following
code:
list<Student_Info> extract_fails(list<Student_Info> & students) {
list<Student_Info> fail;
list<Student_Info>::iterator iter = students.begin();
while (iter != students.end())
if (fgrade(*iter)) {
fail.push_back(*iter);
iter = students.erase(iter);
}
else
++iter;
return fail
}
Be sure to clearly state your assumptions.
Because operations on iterators are constant time, the worst-case estimates for
the atomic statements are
O(1)
list<Student_Info>::iterator iter = O(1)
while (iter != O(1))
if (fgrade(O(1))) {
fail.push_back(O(1));
iter = students.erase(O(1));
}
else
O(1);
return fail
Creating a list takes constant time, but assigning one list to another takes
O(n), where n is the number of elements in the list. Inequality
takes constant time, as does fgrade()
. Pushing back and erasing from a
list also takes constant time, which gives
O(1)
O(n)
while (O(1))
if O(1) {
O(1)
O(1)
}
else
O(1);
return fail
The if rule reduces the while body to constant time; the while iterates
O(n) times. Returning a list requires a copy, which takes O(n)
time. The anaysis is now
O(1)
O(n)
while O(1) : O(n)
O(1)
O(n)
The while and sequence rules reduce the analisys to an O(n) execution
time.