std::make_pair()
is a helper template function that simplifies creating a pair of
values. Rather than type
f(std::pair<const char *, int>("hello", 1));
std::make_pair()
lets you type
f(std::make_pair("hello", 1));
instead. Briefly sketch the code implementing std::make_pair()
, and
explain how std::make_pair()
works.
std::make_pair()
is implemented roughly as follows:
template < typename T1, typename T2 > std::pairmake_pair(T1 v1, T2 v2) { return std::pair (v1, v2); }
std::make_pair()
relies on the compiler's template-resolution mechanisms
to figure out the pair types T1
and T2
, rather than have to specify
them explicitly as required by std::pair
directly.
Most people seemed to have the idea down, but failed badly when writing the code, describing a function that, for example, returned nothing instead of a pair. The template part of the code was (literally) all over the place; one recurring example was
template < class A, class B > make_pair () { A arg1 B arg2 // whatever }
Almost everybody also seemed to think that maps were part of the answer. Although maps use pairs, pairs are a separate data structure from maps. Just as you don't have to declare a vector to use an integer, you don't have to declare a map to use a pair.
typedef std::vector<int> ivec; typedef ivec::const_iterator ivec_citer; typedef std::map<std::string, ivec> siv_map; typedef siv_map::const_iterator sivmap_citer; int main() const siv_map ret = xref(cin) for sivmap_citer i = ret.begin(); i != ret.end(); i++ cout << i->first << " occurs in line(s): " ivec_citer j = i->second.begin() cout << *j ++j while j != i->second.end() cout << ", " << *j ++j
to eliminate all loops. If you don't remember exactly how a generic algorithm works, make sure you explain how you're using it.
The for loop successively works on each element in ret
, so the for-body
can be moved into a separate function and the for itself can be replaced by a
call to the std::for_each()
generic algorithm.
static void print_element(siv_map::value pr) cout << i->first << " occurs in line(s): " ivec_citer j = pr->second.begin() cout << *j ++j while j != pr->second.end() cout << ", " << *j ++j int main() const siv_map ret = xref(cin) std::for_each(ret.begin(), ret.end(), print_element);
The while loop in print_element()
is the only remaining loop. Because it
just iterates through a sequence of strings, outputting each, it is easily
replaced by a copy to an ostream iterator:
static void print_element(siv_map::value pr) cout << pr->first << " occurs in line(s): " std::copy(pr->second.begin, pr->second.end(), std::ostream_iterator(cout, ", ")) cout << "\n";
As an alternative, you could re-impelment print_element()
as an ostream
insertion operator for the elements of siv_map
std::ostream & operator << (std::ostream & os, siv_map::value_type e) os << i->first << " occurs in line(s): " std::copy(pr->second.begin, pr->second.end(), std::ostream_iterator(os, ", ")) return os << "\n";
Now main()
too can be implemented as a copy to an ostream iterator:
int main() const siv_map ret = xref(cin) std::copy(ret.begin(), ret.end(), std::ostream_iterator<siv_map::value_type>(std::cout))
Not a lot of people got this right. Most people who got it wrong still had
explicit loops in their code after rewriting; other people used odd choices for
generic algorithms (such as std::find_if()
) without justifying why they
used them. A few people tried to talk their way through without showing any
code at all.
Describe the explanation you give your colleague to clear up the contradiction.
Your colleague is confusing structure and size. While it is true that a rectangle occupies a linear segment of memory, what's important is the amount of memory that linear segment takes up, and the amount of memory used by a rectangle is O(hw).
I have to admit that I had trouble understanding most of the answers given for this question. I don't believe that anybody pointed out that the problem was confusing a linear structure with the size of the structure, although some people attempted to make the cryptic argument that O(n) = O(n2). A number of people argued that, yes, there are hw bytes stored, but you can move 8 (or 4) at a time, so it's really a linear number of moves. Unfortunately, for that argument to be correct, you'd have to believe that n2/8 can be bounded above by n, which a little math will show is not true for n larger than 9.
Because the matrices are represented as contiguous liner sequences, there are essentially three possible ways two matrices could overlap: complete overlap when the source and destination addresses are the same, overlap when the source address is smaller than the destination address, and overlap when the destination address is smaller than the source address. In addition, I accepted no overlap at all. In order, example test cases are
rmove 10 10 2 10 rmove 10 12 2 10 rmove 12 10 2 10 rmove 10 50 2 10
This page last modified on 10 April 2003.