Lecture 12.2 Loop Invariants for Designing Array Algorithms
© 2006 Pearson Addison-Wesley. All rights reserved Algorithms An important aspect of problem solving is the creation of algorithms. How does a programmer create an algorithm? Often this occurs by recognizing that the problem fits some pattern. What coding/design patterns do you know? Often programming requires knowledge of how to approach problems object-oriented strategies design by prototype top-down design Programming == Problem Solving
© 2006 Pearson Addison-Wesley. All rights reserved Loop Design loopInitialization ; while ( loopCondition ) { workOfTheLoop ; makeProgress ; } loopInitialization ; while ( loopCondition ) { workOfTheLoop ; makeProgress ; } The basic loop pattern Examples list.reset(); while ( list.hasNext() ) { System.out.println( (String)list.next() ); } int k = 1; min = intArray[0]; while ( k != intArray.length ) { if (intArray[k] < min) { min = intArray[k]; } k++; }
© 2006 Pearson Addison-Wesley. All rights reserved diagram - diagram - diagram Pictures are a helpful way to visualize algorithms (especially when using containers). int k = 1; min = intArray[0]; while ( k != intArray.length ) { if (intArray[k] < min) { min = intArray[k]; } k++; } [0] [1] [2]... [k][length-1] processed This picture captures an important property of the loop -- the loop ___________.
© 2006 Pearson Addison-Wesley. All rights reserved Loop Invariant A loop invariant is an assertion that is true immediately before the loop condition. int k = 1; min = intArray[0]; while ( k != intArray.length ) { if (intArray[k] < min) { min = intArray[k]; } k++; } [0] [1] [2]...[k] [length-1] processed INV: All values within intArray[0]... intArray[k-1] are ≥ min & some value of intArray[0]... intArray[k-1] == min
© 2006 Pearson Addison-Wesley. All rights reserved Trace [0] [1] [length-1] processed int k = 1; min = intArray[0]; while ( k != intArray.length ) { if (intArray[k] < min) { min = intArray[k]; } k++; } INV: All values within intArray[0]... intArray[k-1] are ≥ min & some value of intArray[0]... intArray[k-1] == min Just before the loop k 1 INV: All values within intArray[0]... intArray[0] are ≥ min & some value of intArray[0]... intArray[0] == min
© 2006 Pearson Addison-Wesley. All rights reserved Reversing an Array What is wrong with this initial attempt at reversing the content of an array? char tmpChar; int k = 0; while ( k != charArr.length ) { tmpChar = charArr[k]; charArr[k] = charArr[charArr.length-k-1]; charArr[charArr.length-k-1] = tmpChar; k++; } Consider how the loop invariant captures this problem... INV: for all j, (0 ≤ j < k) charArr[j] == [0] [1] [2]... [j] [length-j-1] [length-1]
© 2006 Pearson Addison-Wesley. All rights reserved Coding from the Invariant 1) Select the loop invariant. 2) Determine initialization code. 3) Determine the loop condition. 4) Complete the loop body. loopInitialization ; while /* loopInvariant */ ( loopCondition ) { loopBody ; } Four Steps
© 2006 Pearson Addison-Wesley. All rights reserved Example: Coding from the Invariant 1) Select the loop invariant. 2) Determine the loop condition. 3) Determine the initialization. 4) Complete the loop body. // Assert: n is an int and n ≥ 0 loopInitialization ; while /* loopInvariant */ ( loopCondition ) { loopBody ; } // Assert: factorial == n! Four Steps Design a loop to calculate n factorial, written n! n! == 1 * 2 * 3 * 4 *... * n 3! == 1 * 2 * 3 == 6 5! == ?? Note, also, the following... 1! == 1 0! == 1
© 2006 Pearson Addison-Wesley. All rights reserved Design a loop to calculate n factorial, written n! Below is a suitable invariant for some int variable, called counter. 1) Select the loop invariant. 2) Determine the loop condition. 3) Determine the initialization. 4) Complete the loop body. // Assert: n ≥ 0 loopInitialization ; while /* loopInvariant */ ( loopCondition ) { loopBody ; } // Assert: factorial == n! Four Steps Example: Coding from the Invariant
© 2006 Pearson Addison-Wesley. All rights reserved Design a loop to calculate n factorial, written n! What loop condition combines with the invariant to ensure the assertion after the loop? (i.e., what value for counter must terminate the loop?) 1) Select the loop invariant. 2) Determine the loop condition. 3) Determine the initialization. 4) Complete the loop body. // Assert: n ≥ 0 loopInitialization ; while /* factorial == counter! */ ( loopCondition ) { loopBody ; } // Assert: factorial == n! Four Steps Example: Coding from the Invariant
© 2006 Pearson Addison-Wesley. All rights reserved Design a loop to calculate n factorial, written n! What loop initial values need to be assigned to counter and factorial for the loop invariant to be true when the loop begins? 1) Select the loop invariant. 2) Determine the loop condition. 3) Determine the initialization. 4) Complete the loop body. // Assert: n ≥ 0 loopInitialization ; while /* factorial == counter! */ ( counter != n ) { loopBody ; } // Assert: factorial == n! Four Steps Example: Coding from the Invariant
© 2006 Pearson Addison-Wesley. All rights reserved Design a loop to calculate n factorial, written n! What loop body both preserves the loop invariant and makes progress? counter++; factorial = factorial * counter; 1) Select the loop invariant. 2) Determine the loop condition. 3) Determine the initialization. 4) Complete the loop body. // Assert: n ≥ 0 counter = 0; factorial = 1; while /* factorial == counter! */ ( counter != n ) { loopBody ; } // Assert: factorial == n! Four Steps Example: Coding from the Invariant
© 2006 Pearson Addison-Wesley. All rights reserved The Complete Loop 1) Select the loop invariant. 2) Determine the loop condition. 3) Determine the initialization. 4) Complete the loop body. // Assert: n ≥ 0 counter = 0; factorial = 1; while /* factorial == counter! */ ( counter != n ) { counter++; factorial = factorial * counter; } // Assert: factorial == n! Four Steps Example: Coding from the Invariant