270 likes | 416 Views
Informatik I (D-ITET) Group 7, 15:00-17:00, ETZ H91 Assistant: Ercan Ucan. Slides at http://people.inf.ethz.ch/eucan/inf-1 /. Exercise 6 ( 05 /11/2012 ) . Bubble sort. Pseudo-code (from Wikipedia): bubbleSort ( array A ) repeat swapped = false
E N D
Informatik I (D-ITET)Group 7, 15:00-17:00, ETZ H91Assistant: Ercan Ucan Slides at http://people.inf.ethz.ch/eucan/inf-1/ Exercise6(05/11/2012)
Bubble sort • Pseudo-code (from Wikipedia): bubbleSort( array A ) repeat swapped = false for i = 1 to length(A) - 1 do: if A[i-1] > A[i] then swap( A[i-1], A[i] ) swapped = true end if end for until not swapped end procedure • The bubble sort algorithm can be easily optimized by observing that the n-th pass finds the n-th largest element and puts it into its final place. So, the inner loop can avoid looking at the last n-1 items when running for the n-th time Section - Subsection
Selection sort • Algorithm pseudo-code(from Wikipedia): • Find the minimum value in the list • Swap it with the value in the first position • Repeat the steps above for the remainder of the list (starting at the second position and advancing each time) Section - Subsection
Selection sort /* a[0] to a[n-1] is the array to sort */ inti,j; intiMin; /* advance the position through the entire array */ /* (could do j < n-1 because single element is also min element) */ for (j = 0; j < n-1; j++) { /* find the min element in the unsorted a[j .. n-1] */ /* assume the min is the first element */ iMin= j; /* test against elements after j to find the smallest */ for ( i = j+1; i < n; i++) { /* if this element is less, then it is the new minimum */ if (a[i] < a[iMin]) { /* found new minimum; remember its index */ iMin= i; } } /*iMinis the index of the minimum element.Swap with the current position */ if ( iMin != j ) { swap(a[j], a[iMin]); } } Section - Subsection
Bubble sort vs. Selection sort • Bubble sort: • Max numberofcomparisons:N * (N-1) / 2 • Min numberofcomparisons: N - 1 • Selection sort • Min andmaxnumberofcomparisons: N * (N-1) / 2 Section - Subsection
General – Programming practice • Do not include any libraries that are not GNU standard. • Do not include any libraries that you do not need in your program. • Prefer to use the given library functions instead of writing your own. (code reuse and less debugging hassle) • Do not use variable names with German (or any other non-standard) letters. It is not GNU compliant! Section - Subsection
Every variable in C++ has: Name: what is it called? Address: where in memory is it? Type: how to interpret the value Value: what is stored at the address C++ pointers are variables that contain the addresses of other variables. Java has no pointers (only object references), C# has them only in “unsafe code” // px is a ptr to an integer int *px; // x is an integer int x; // px gets the address of x // or px points to x px = &x; // x gets the contents of // whatever x points to x = *px Pointers
int* int* int int int* int 0 3 5 3 number number_ptr number_ptr number number_ptr number Pointers intnumber= 3; int *number_ptr= NULL; number_ptr= &number; number= 5;
int* int int* int int 7 7 7 number_ptr number number_ptr number x Pointers *number_ptr= 7; int x = *number_ptr;
int* int int int* 7 7 number_ptr number x y_ptr Pointers int *y_ptr= number_ptr;
int* int int int* 6 7 number_ptr number x y_ptr Pointers *y_ptr = 6;
int* int int int* 6 7 number_ptr number x y_ptr Pointers y_ptr = &x;
int* int int int* int** 6 7 number_ptr number x y_ptr p_ptr_ptr Pointers int **p_ptr_ptr; p_ptr_ptr = &number_ptr;
int* int int int* int** 7 5 number_ptr number x y_ptr p_ptr_ptr Pointers *(*p_ptr_ptr) = 5;
Pointers (Reference Operator - &) • The address that locates a variable within memory is called a reference to that variable. • We can obtain the reference to a variable using the reference operator (&) before the identifier of the variable ( you can translate it as “& = address of” ). • Example: • andy = 25; • fred = andy; • ted = &andy; Pointers (Dereference Operator - *) • Used if you want to access the value stored in the variable that a pointer points to. • Example: • tom = *ted; • Note the difference with • tom = ted;
Pointers (Declaring and Initializing) • dataType * pointer ; (e.g. int * p1; int* p1; int *p1;) • A pointer variable is never just a pointer. It is always a pointer to a specific data type. • Other examples: • int *p1, p2; (Here p2 IS NOT a pointer) • double *p3; • char *p4; • Note that whereas p1, p3 and p4 point to data types of different sizes, all the three pointer variables are typically of the same size (The address of a big department store is of the same length as the address of a small house). • Initialize: • int age = 26; • int *pt = &age; • Remember the string definition: • char *message = “hello”; 1702 1703 1704 1705 1706 1707 message 1702
Pointers (Declaring and Initializing) • !! Be careful !! • When you declare a pointer, you DO NOT allocate space for the data to which the pointer points. • You always have to make sure that you have created space for the data. For example: • long *fellow; • *fellow = 12354134; // Where is the value 12354134 stored? We can’t say • (The NULL pointer) The constant NULL is a special pointer value which encodes the idea of “points to nothing”. But it is a runtime error if you try to dereference it. • (Pointer Assignment) The assignment operator (=) between two pointers make them point to the same memory address. Pointer Golden Rule: Always initialize a pointer to a definite and appropriate address before you apply the dereferencing operator (*) to it.
Pointers (Arithmetics) • Arithmetical operations: Only addition and subtraction are allowed . • Suppose that we define the following three pointers: • char *mychar; (char reserves 1 Byte) • short *myshort; (short reserves 2 Byte) • long *mylong; (long reserves 4 Byte) • So, now, if we write: • mychar++; • myshort++; • mylong++; • When adding one to a pointer we are making it to point to the following element of the same type.
Pointers (Dynamic Memory) • Until now, we were only reserving a fixed amount of memory for our variables during the compilation of our program. But what if we need a variable amount of memory that can be determined during runtime? The answer is Dynamic Memory. • To request dynamic memory we use the operator new. It returns a pointer to the beginning of the new block of the allocated memory. • pointer = new type ; • pointer = new type [number_of_elements]; • Example: • int * bobby; • bobby = new int [5]; • *bobby (or bobby[0]) indexes the first element, *(bobby+1) (or bobby[1]) the second element etc. • When you no longer need the memory you have allocated you have to free it, using delete • delete pointer; • delete [] pointer; • The first expression should be used to delete memory allocated for a single element and the second one for memory allocated for arrays of elements. int bobby
Pointers (to Structures) • Suppose we define a structure: • struct movies { • string title; • int year; • }; • movies amovie; • movies *pmovie; • pmovie = &amovie; • Use the arrow operator (->) to dereference pointers that point to objects with members, like structs. • For example, • pmovie -> title is equivalent to (*pmovie).title Pointer to structure movies
Exercise 1 (Stacks) • A stack is a Last-In-First-Out (LIFO) data structure. • A stack can have any abstract data type as an element, but is characterized only by two fundamental operations: push() and pop(). • The push operation adds an element to the top of the list, hiding any elements already present on the stack or initializing if it is empty. • The pop operation removes an item from the top of the list and returns its value to the caller. Empty stack first = 15 second = 10 third = 5 push(5) 5 10 10 first = pop(); third = pop(); second = pop(); push(10) 5 5 5 15 Empty stack push(15) 10 5
//Dieses FunktionimplementierteineTestumgebungfür den Stack void test() { cout << "The program has been startet without any arguments." << endl; cout << "The program enters the stack test mode:" << endl; cout << "Enter one of the commands: push, pop, end" << endl; string command; do{ cin >> command; if (command == "pop"){ cout << pop() << endl; } else if (command == "push"){ cout << "element?"; intelementToPush; cin >> elementToPush; push(elementToPush); } else if(command == "end"){ clear(); } else {cout << "command not recognised"<< endl;}; }while(command != "end"); } int main(intargc, char * argv[]){ init(); test(); clear(); return 0; } Exercise 1 (Stacks) void init() { //TODO: Code hiereinfügen } int pop(){ //TODO: Code hiereinfügen } void push(int element){ //TODO: Code hiereinfügen } int size() { //TODO: Code hiereinfügen } void clear() { //TODO: Code hiereinfügen }
Exercise 1 (Stacks – Implemented via Dynamic Arrays) • Initialize the stack as a dynamic array: • data = new int[2]; • numberofElements = 0; • When you pop() reduce the number of elements by one and return the top element. • If the result is an empty stack, report “Stack is empty” and return -1. • When you push() add the element in the top of the stack. If the array is already full, make a new dynamic array of double the size and copy the old one there.
Exercise 1 (Stacks – Implemented via Linked Lists) struct element struct element struct element element *next element *next element *next element *first NULL intvalue intvalue intvalue
Exercise 2 (Parenthesis Matching) • Test for parenthesis matching: • ( 5 * ( 2 + sqrt ( x ) ) ) [Expr. 1] • for ( i = 1 ; i <=5 ; i++ ) { cout << i; } [Expr. 2] • Input via int main(intargc, char* argv[]) {…} • e.g. • ./matchParentheses “( 5 * ( 2 + sqrt ( x ) ) )” • means that • argv[1] is a variable of type string where the expression is stored. • You should now have a string that contains the input expression. The analysis step require to go through the elements of the expression and test the following:
Exercise 2 (Parenthesis Matching) • (Case 1) All parentheses ‘()’ and brackets ‘{}’ match correctly. Take care of nested parentheses and/or brackets. For example: • ( ( { } ) ) correct • ( { { } } ) correct • In this case print “Parentheses match OK !!” and exit. • (Case 2) There is a parenthesis or bracket mismatch. This means that while you have opened a parenthesis ‘(‘ you use a closing bracket ‘}’ instead of a closing parenthesis ‘)’ and the other way around, opening bracket ‘{‘ and closing parenthesis ‘)’ instead of ‘}’ . For example: • ( ( { } } ) notcorrect • ( ( {) ) ) notcorrect • For the two cases print • ( has opened, but closing } encountered !! • Parentheses do not match • or • { has opened, but closing ) encountered !! • Parentheses do not match • respectively and exit. • (Case 3) Finally, you have to test if there is an opening parenthesis ‘(‘ or bracket ‘{‘ but there is no closing symbol at all. For example: • ( ( { } ) notcorrect – unmatched ( • { ( { } ) notcorrect – unmatched { • In this case print • ( not closed at all !! • Parentheses do not match • or • { not closed at all !! • Parentheses do not match • respectively and exit.
Exercise 2 (Parenthesis Matching) • Now the question arises how you are going to implement the above goals. You have to use your preferred stack implementation (by dynamic arrays or pointers) from exercise 1 with one small modification. You have to modify slightly your stack in order to store a character in each element (instead of an integer). The way you will use the stack is pretty simple: • While you are reading opening parentheses ‘(‘ or brackets ‘{‘ push the respective symbols in the stack. • Ignore all the symbols and operators that are not parentheses or brackets. We do not want to evaluate the expression. We just want to see if the parentheses are matching. That’s why the stack only has to store the parentheses and/or brackets. • If you read a closing parenthesis ‘)’ or bracket ‘}’ pop the first stack element and compare it with the one you just read. In order to compareuse the normal comparison operators (for example, x == ‘)’ or x!=’0’. Based on the result of the comparison differentiate between the cases we analyze above. • When is case 3 applied?