notes on labs and assignments. commenting revisited you have probably been able to “get away”...

39
Notes on Labs and Assignments

Post on 20-Dec-2015

213 views

Category:

Documents


0 download

TRANSCRIPT

Notes on Labs and Assignments

Commenting Revisited

You have probably been able to “get away” with poor inline documentation is labs Tasks are straightforward Often only one key method is involved

On assignments this is not going to work Bigger variety of solutions Tougher to follow as a marker (or user)

The Header Comment

It is good practice to include an initial comment in the source file for each class

/* AlphaChars.javaAuthor: Aaron HunterDate: September 26, 2006CMPT 126 - Lab 2Provides methods to check if astring contains letters.

*/

Method Descriptions

It is also good practice to include a comment preceding each method

/*Checks if a single character is a letter.*/

public static boolean isAlpha( char c)

{

if (((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')))

return true;

else

return false;

}

Another Method

/* Checks if a string contains all letters. */public static boolean isAllAlpha(String s){

for(int i=0; i<s.length(); i++){

\\ Check each character. If not a letter, \\ return false.if(!isAlpha(s.charAt(i)))

return false;}\\ If the loop completes without returning false, \\ then everything is a letter and we should \\ \\ \\ return true.return true;

}

Another Method

/* Checks if a string contains all letters. */public static boolean isAllAlpha(String s){

for(int i=0; i<s.length(); i++){

if(!isAlpha(s.charAt(i)))return false;

}

return true;}

Abstracting The General Problem Given a method hasProperty(Type x)

checks if x has some property, returns true if it does

Given a variable xArray of type Type[] : Does every element of xArray have the property? Does some element of xArray have the property? Do no elements of xArray have the property?

Solution – All

public static boolean allHaveProperty(Type[] xArray)

{

for(int i=0; i<xArray.length; i++)

{

if(!hasProperty(xArray[i]))

return false;

}

return true;

}

Solution – Some

public static boolean someHaveProperty(Type[] xArray)

{

for(int i=0; i<xArray.length; i++)

{

if(hasProperty(xArray[i]))

return true;

}

return false;

}

Solution – None

public static boolean noneHaveProperty(Type[] xArray)

{

for(int i=0; i<xArray.length; i++)

{

if(hasProperty(xArray[i]))

return false;

}

return true;

}

Lab 2 – Basic Comments

Use comments comments before methods comments about important bits of code

e.g. Why are you casting a char to an int?

Use sub-methods if you are copying and pasting lots of code, maybe

you need another method Make the code testable

Running Time

Speed

When writing programs, we often want them to be fast

Several things affect this: The algorithm that is implemented The way the algorithm is implemented Programming language used Capabilities of the hardware

We won’t worry about the 3rd and 4th points

Algorithm vs. Implementation The algorithm is the step by step procedure

used to solve a problem One problem can be solved by different

algorithms e.g. linear search vs. binary search

One algorithm can be implemented in different ways in Java e.g. linear search with a for loop vs. linear search with

a while loop

Algorithm vs. Implementation So… the algorithm is the procedure that is

used to solve the problem … the implementation of the algorithm is the

way the algorithm is described in Java (or some other programming language)

Algorithms are the kind of thing we can describe with pseudo-code – implementations are described in Java.

Implementation

For a given algorithm, there will be many ways it can be implemented e.g. loop forward or backwards, order of if

conditions, how to split into methods, lazy/active boolean operators…

some of these affect the speed of the program No rules here: programming experience

helps so does knowledge of system architecture,

compilers, interpreters, language features,…

Algorithm Analysis

To analyze an algorithm is to determine the amount of “resources” needed for execution

Typically there are two key resources: Time Space (memory)

We will only be concerned with running time today

Algorithm Analysis

Donald Knuth (1938--) pioneer in algorithm analysis wrote “The Art of Programming” (I-III)

mails $2.56 for every error found developed the Tex typesetting system bible analysis through random sampling

"Beware of bugs in the above code; I have only proved it correct, not tried it."

Algorithm Analysis

The inherent running time of an algorithm almost always overshadows the implementation e.g. There is nothing we can do to make Power1

run as fast as Power2 (for large values of y)

e.g. For sorted arrays, binary search is always faster (for large arrays, in the worst case)

Measuring Running Time

To evaluate the efficiency of an algorithm: We can’t just time it

Different architectures, hidden processes, etc. Need something that allows us to generalize

Idea: count the number of “steps” required For an input of size n

Will be measured in terms of “Big-O” notation

Measuring Running Time

We define algorithms for any input (of appropriate type)

What is the size of the input? For numerical inputs… it is just the input value n For string inputs… normally the length

What is a step? Normally it is one command

Actual Running Time

Consider the following pseudocode algorithm:

Given input n

int[] n_by_n = new int[n][n];

for i<n,j<n

set n_by_n[i][j] = random();

print “The random array is created”;

Actual Running Time

How many steps does it take for input n? 1 step: declare an n by n array n2 steps: put random numbers in the array 1 step: print out the final statement

Total steps: n2 + 2 Note: the extra 2 steps don’t carry the same

importance as the n2 steps as n gets big… the extra two steps are negligible

Actual Running Time

We also think of constants as negligible we want to say n2 and c*n2 have “essentially” the

same running time as n increases more accurately: the same asymptotic running

time Commercial programmers would argue

here… constants can matter in practice

Actual Running Time

But for large n, the constants don’t matter nearly as much

Plug in n=1000 n2+500 = 1000500 [+500] 2n2 = 2000000 [+100000] n3 = 1000000000 [+999000000] 2n = 10301 (approx) [+ 10301 ]

Big O Notation

Running time will be measured with Big-O notation

Big-O is a way to indicate how fast a function grows

e.g. “Linear search has running time O(n) for an array of length n” indicates that linear search takes about O(n) steps

Big-O Notation

When we say an algorithm has running time O(n): we are saying it runs in the same time as other

functions with time O(n) we are describing the running time ignoring

constants we are concerned with large values of n

Big-O Rules

Ignore constants: O(c * f(n)) = O(f(n))

Ignore smaller powers: O(n3 + n) = O(n3)

Logarithms cost less than a power Think of log n as equvialent to n0.000….001

O(na+0.1) > O(na log n) > O(na) e.g. O(n log n + n) = O(n log n) e.g. O(n log n +n2) = O(n2)

Why Big-O?

Look at what happens for large inputs small problems are easy to do quickly big problems are more interesting larger function makes a huge difference for big n

Ignores irrelevant details Constants and lower order terms depend on

implementation Don’t worry about that until we’ve got a good

algorithm

Running Time Graphs

Determining Running Time

Need to count the number of “steps” to complete need to consider the worst case for input of size n a “step” must take constant (O(1)) time

Often: iterations of the inner loop * work per loop recursive calls * work per call

Why Does log Keep Coming Up? By default, we write log n for log2 n High school math:

logb c = e means be = c

so: log2 n is the inverse of 2n

log2 n is the power of 2 that gives result n

Why Does log Keep Coming Up? Exponential algorithm – O(2n)

Increasing input by 1 doubles running time Logarithmic algorithm – log n

The inverse of doubling… Doubling input size increases running time by 1 Intuition:

O(log n) means that every step in the algorithm divides the problem size in half

Example 1: Search

Linear search: checks each element in array does some other stuff in java implementation…

but just a constant number of steps O(n) - “order n”

Binary search chops array in half with each step n n/2 n/4 n/8 …. 2 1 takes log n steps: O(log n) - “order log n”

Example 2

Power 1: xy = x * xy-1

makes y recursive calls: O(y) Power 2:

xy = xy/2 * xy/2

Makes log y recursive calls: O(log y) Had to be careful not to compute xy/2 twice

Would have created a O(y) algorithm Instead: calculated once and stored in a variable

Computational Complexity

All of this falls in the larger field of computational complexity theory

Historically: recursion theory: what can be computed?

not everything it turns out complexity theory: given a computable function,

how much time and space are needed?

Computational Complexity

Polynomial good, exponential bad polynomial time = O(nk) for any k exponential time = basically O(2n)

This is a big jump in time Will not be bridged by “faster computers”

polynomial algorithm on modern computer <1 second for large n

exponential algorithm can be in the centuries 1000 times faster computers… still in the

centuries

Non-Deterministic Algorithms Allow the algorithm to “guess” a value and

assume it is right Det: check if a student is enrolled in CMPT 126 Non: find a student enrolled in CMPT 126

Intuitively: finding an example is harder than checking an example

The big question:

Can non-deterministic polynomial algorithms be captured with deterministic ones?

Non-Deterministic Algorithms Commonly called the “P=NP” problem Open for 30 years Currently there is a 1 million dollar prize for a

solution (from the Clay Institute) All modern cryptography and e-commerce

relies on the (unproved) assumption of a solution