CS62 - Spring 2011 - Lecture 40

  • Admin
       - CS alumni talks today 3-4PM in Edmunds 114
       - anyone need a partner for assignment 11?
       - I've provided you with code to generate some test graphs. Use it!

  • Dijstra's algorithms: some final points
       - why is it called the "single source shortest paths" problem?
          - we find the shortest paths from a given vertex to all other vertices
       - if we only want to find shortest path between two nodes, why do we find all of them?
          - asymptotically, no faster
          - though, we could stop early if we were just interested in the single path
       - what would happen if the weights of the graphs were negative?
          - algorithms doesn't work anymore :(
          - Dijkstra's only works on non-negative weighted graphs
       - run-time analysis

  • operator overloading
       - we saw how to overload the = operator
       - in general, you can overload almost any operator (there are a few exceptions, though)
       - basic steps:
          - add the appropriate function header for the operator
             - the function names all start with "operator" followed by the actual operator
             - you just have to get the number of arguments and the return type correct, but you should be able to figure it out
             - http://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B
          - add the function definition to the .cpp file
             - make sure you know what you're doing, since operators are important :)
       - look at operator[] overload in the linked list class in linkedlistfinal.cpp code
          - int& LinkedList::operator[](unsigned int index)
             - overriding the [] operator of the LinkedList class
             - why an unsigned int?
                - can't have negative indices
             - why the int& return type?
                - our linked list is storing ints
                - it needs to be return-by reference and not value, so we can do things like:
             
                   LinkedList l;
                   ...
                   l[4] = 7;

                   and actually have it change the data. Since the int returned from the operator method is the SAME as the one we're modifying in the statement. Make sure you understand this distinction!

  • templates
       - what are "generics" in Java?
          - generics are a way for us to write classes that can be instantiated for many different types
          - For example:
             ArrayList<Integer>
             ArrayList<String>
          - Why do we have them? What do they do for us?
             - make the code cleaner, since we don't always have to typecast back from Object
             - type safe: the compiler can check the types of more things for us
       - Any problems with generics in Java?
          - They can only be a class type (not a built-in type). This requires us to have the wrapper classes Integer, Double, Float, etc.
          - They're optional: we can still get around them if we want to
          - The type information is lost at runtime (more on this later), so we can't say something like "new T()" or "new T[]"
       - How do we define them in Java?
          - define a type variable(s) when we define the class

          public class MyClass<T>

          or

          public class MyClass<K, V>

       - C++ has a similar idea, called "templates"
       - template functions
          - in Java, everything is inside a class
          - in C++, we can define functions not inside classes
          - we can templatize a function in a similar way Java, by defining a type variable
          
             template <typename T> // where T is the name of our type variable
             void myFunction(){

             }

          - After that, we can use the type variable just like in Java
          - look at templatefunctions.cpp in templates.cpp code
             - we've defined three different templatized functions
             - notice that these are NOT in any class. They are just standalone functions
             - for each function, we have to declare a new type variable
          - what will be printed out in the main method?
             equals(5, 10): 0
             equals(10, 10): 1
             equals("test", "test"): 1
             add(5, 10): 1
             getMax: 99
          - notice that we can call equals with a variety of different types
          - notice also that unlike Java, built-in types are fine (we've seen this before with the STL classes)
          - how are generics implemented in Java?
             - at compile-time, the compiler checks to make sure that all of the typing is correct
             - then, all of the generics are removed, e.g. ArrayList<Integer> goes back to ArrayList
                - this process is called type erasure
             - why can we do this?
                - All objects inherit from Object
                - this is why we can't do it for built-in types
                - and why we can't say something like "new T()", at run-time, it doesn't know what that is!
          - the way that this actually happens in C++, is that each time we call it with a different type, the compiler creates a NEW instance of the function with the types instantiated
             - in the above examples, the compiler would create TWO different versions of the equals function

                bool equals(int a, int b)
       
                bool equals(char* a, char* b)
       
          - what would happen if we uncommented the two "cout" lines?
             - it won't compile
             - for equals, they have two different types and so T can't be both int and char*
             - for the second, cout the compiler will try and instantiate add:         
                char* add(char* a, char* b)
          
                - for add, + isn't defined for char*
          - what would happen if we created a vector of our own class, say MyClass and then tried to call getMax, e.g.
             vector<MyClass> v;

             getMax(v)

             - the compiler will try and instantiate getMax

                MyClass getMax(const vector<MyClass>& V)

             - unless MyClass has overridden the > operator, then I will get a compiler error
       - templates in classes
          - like in Java, we can also define templatized classes using a similar terminology

             template <typename T>
             class MyClass{
                // I can use T as a type like in Java
             };

          - Unfortunately, if we want to separate our code into .h and .cpp files, templates are a pain
             - The .h file looks like you'd expect
             - In the .cpp file, each function need to be a templatized function and we wherever we have MyClass::, we must templatize that too, to MyClass<T>::
          - So, often, when doing templates, we put all of the code including the class definition in the .cpp file
          - Look at cell.cpp in templates.cpp code
             - we define the type variable at the top with the class definition
             - we can use it throughout the functions, just like we did in Java
             - notice now we can instantiate Cell's of different types
             - will this compile?
             - what will be printed out?
                An int: 10
                A string: a string
                A vector: 10
       - look at linkedlisttemplate.cpp code
          - here is a more elaborate use of templates with our linkedlist class
          - in node.cpp, we defined the Node class to be templatized
             - why do we now have ifndef, define, etc. in the node.cpp class?
                - because the implementation is now in the node.cpp class, we'll need to include node.cpp
                - and we'll therefore need to make sure that we only include it once in a compilation
          - in linkedlist.cpp
             - we include "node.cpp"
             - we can then use the templatized version of node.cpp
          - in linkedlisttest.cpp
             - we can instantiate different versions of our LinkedList class depending on what we want to store

  • command-line fun
       - you've started to use a lot of different commands on the command line to do different things
       - which ones have you used/seen?
       - Here are some other things that might be useful
          - <tab> completion
             - if you hit the <tab> key, it looks at the local directory and tries to autocomplete it based on what files are available
             - it will go as far as it can until there is ambiguity
             - if it is ambiguous and you hit <tab> twice, it will list the options
          - cat <filename1> [filename2]
             - prints the contents of the file to stdout (i.e. to the screen)
          - head <filename>
             - prints the first 10 lines of the file to stdout
          - head -n <num> <filename>
             - prints the first <num> lines of the file to stdout
          - tail <filename>
             - print the last 10 lines of the file to stdout
          - tail -n <num> <filename>
             - print the last <num> lines of the file to stdout
          - egrep "pattern" <filename>
             - prints the lines in a file that contain pattern
             - can just be a string
             - or can also be a regular expression
             - many options/variations
          - wc <filename>
             - count the number of characters, words and lines in a file
             - you can call it with the flags: -c, -w and -l to get any individual one
          - man <command>
             - get the manual description for a command
             - e.g. "man ls" or "man egrep"
          - less <filename>
             - simple commandline file viewer with up and down scrolling
             - spacebar jumps down a page
          - who
             - see who else is logged into this computer
          - whoami
             - figure out what your username is
          - top
             - see what processes are running
          - sort <filename>
             - sorts a file (using an on-disk sorting algorightm)
       - piping
          - '>' sends the output from stdout to a file
             - ls > out
                will send the output of ls to the file named out
             - head -n 100 file > blah
                will send the first 100 lines of "file" to "blah"
          - '<' sends the input from a file as if it were entered into the console from the user
          - '|' sends the stdout from the first command to the stdin of the second command
             head -n 100 file | tail -n 1

             get the 100th line from a file