Templates: As a rule, whenever you find yourself doing the same... almost the same thing (so the instances vary in a...

advertisement
Templates:
As a rule, whenever you find yourself doing the same thing over and over again, or
almost the same thing (so the instances vary in a systematic way), you should think
about having a computer do it.
This is what computers are good at. This saves human labor and eliminates many
errors, since if you don't have to repeat things, you are less likely to make
mistakes.
Abstraction Principle: Avoid writing the same thing over and over. Instead abstract
out the recurring pattern and give it a name.
We have seen many examples, for example, functional abstraction and class
abstraction.
Suppose I tell you how to exchange (or swap) the contents of two double variables.
So I say, to swap a and b, do the following:
double temp; // a temporary
temp = a;
(*)
// save a
a = b;
b = temp;
So this an idiom you learn early on. You have to be a little bit careful, or you'll get it
wrong (e.g., write "b = a" instead of "a = b").
If you are going to be doing a lot a swapping, it makes sense to define a
swapdouble function:
void swapdouble (double& x, double& y) {
double temp = x;
x = y;
y = temp;
}
To swap doubles I can use this function:
double a, b, c, d;
...
swapdouble (a, b); // this does what the previous code (*) did
swapdouble (c, d); // swaps c, d
This is an example of functional abstraction.
But what about swapping integers? Clearly it's the same pattern, but with "double"
replace by "int":
void swapint (int& x, int& y) {
int temp = x;
x = y;
y = temp;
}
int aa, bb;
vector<int> V (100);
swapint (aa, bb);
swapint (bb, V[20]);
I could give you a general template for a swap function, and tell you, "all you have
to do is replace "SOMETYPE" with the type of variables you want to swap, and put it
in your program." You could do this with a text editor. Here is the "template":
void swapSOMETYPE (SOMETYPE& x, SOMETYPE& y) {
SOMETYPE temp = x;
x = y;
y = temp;
}
Fortunately, C++ has the "template" feature, which does this automatically. I can
define generic swap function this way (generic because it works on any classes of
objects):
template <class SOMETYPE>
void swap (SOMETYPE& x, SOMETYPE& y) {
SOMETYPE temp = x;
x = y;
y = temp;
}
double a, b, c, d;
int aa, bb;
vector<int> V (100);
swap (a, b);
swap (c, d);
swap (aa, bb);
swap (bb, V[20]);
Card AD (ACE, DIAMOND);
Card KC (KING, CLUB);
swap (AD, KC);
Recall that vectors (and lists and stacks) are standard extensions to the C++ core
language defined in the STL = Standard Template Library.
Things like vectors are "templated"; that's why we write
vector<int> V;
vector<double> A;
You can also have "templated" classes and structs, and these are very useful. We'll
look at an example next time.
template <class SOMETYPE>
class C {
..... SOMETYPE ...
}
Searching and Sorting:
Searching and sorting are two very important operations done on computers, and a
lot of time has devoted to designing efficient searching and sorting algorithms.
C.find(D) returns the location of the 1st occurrence of C in D, and -1 if C is not in D.
It does a sequential search, starting at the beginning of the deck.
One thing we do in computer science is analyze the efficiency of programs.
In computing the two resources of most interest are time and space.
Consider time.
If D is a deck of N cards, what is the best case (least time)?
It's the first card, so I go through the loop once (time = 1).
Worst case: it's not in D, so I go N+1 times.
Average case:
We would guess N/2 if it's in the middle of the deck.
More accurately: if each location is equally likely, then the average is:
(1/(N+1)) [1 + 2 + ... + N + (N+1)]
= [(N+1)(N+2)/2] / (N+1)
= (N+2)/2 = O(N)
// check the algebra!
That is, we say it's "of order N," that is, proportional to N.
Sequential search is a linear algorithm (proportional, in the long run, to the size of
the input). That's pretty good.
(We can have quadratic algs. (prop to the square of the size, N^2), exponential
algs., etc.)
If we know the deck is sorted, we can do much better. For example a bisection
search takes time proportional to log N.
E.g., log_2 (64) = 6, so there are 6 bisections: 64, 32, 16, 8, 4, 2, 1.
Download