Title: Announcements
1Announcements
- Homework 3 is due this Wednesday, November 11th
- Superman robot moves into the phone booth.
- Homework 4 will be assigned this week and will be
due next Wednesday, November 18th - First Midterm
- On November 21st Saturday at 900am ( 100
minutes)
2From Selection to Repetition
- The if statement and if/else statement allow a
block of statements to be executed selectively
based on a condition - cout ltlt "Please enter a non-negative number" ltlt
endl - cin gtgt inputnumber
- if (inputnumber lt 0)
-
- cout ltlt inputnumber ltlt " is negative. Wrong
Input" ltlt endl -
- This piece of code does not ask another input
number if the number is negative. - --------------------------------------------------
--------------------------------------------------
-- - The while statement repeatedly executes a block
of statements while the condition is true - cout ltlt " Please enter a non-negative number" ltlt
endl - cin gtgt inputnumber
- while (inputnumber lt 0)
-
- cout ltlt inputnumber ltlt " is negative! Try
again" ltlt endl - cin gtgt inputnumber
-
3Semantics of while loop
- if (test) while (test)
-
- statement list statement list
-
4Sum Example why we need loops?
- We want to find the sum of 10 positive values
- We can write
- int num1, num2, num3, num4, num5
- int sum
- cin gtgt num1 gtgt num2 gtgt num3 gtgt num4 gtgt num5
- sum num1 num2 num3 num4 num5
- cin gtgt num1 gtgt num2 gtgt num3 gtgt num4 gtgt num5
- sum num1 num2 num3 num4 num5
5Sum Example (not in book)
- What if we want to compute the sum of
- 100 values
- an undetermined number of values
- What we need is a program to be able to read as
many values as we want and then compute the sum - This is possible with loops
- Good solution is to use loops.
- Code is developed on board. See sum10nums.cpp
- This type of loops are called counting loops
- number of iterations is known
6Another simple example
- Calculate the sum of the integer numbers between
1 and 10 - int sum 0 // this program piece
- int i 1 // calculates the sum of
- while (i lt 10) // integers between and
- // including 1 and 10
- sum sum i
- i 1
-
7Walkthrough of the example
1
2
i
- int sum 0
- int i 1
- while (i lt 10)
-
- sum sum i
- i i 1
-
- cout ltlt sum
0
1
sum
ilt10
true
false
sumsumi ii1
coutltltsum
8Walkthrough of the example
2
3
i
- int sum 0
- int i 1
- while (i lt 10)
-
- sum sum i
- i i 1
-
- cout ltlt sum
1
3
sum
ilt10
true
false
sumsumi ii1
coutltltsum
9Walkthrough of the example
3
4
i
- int sum 0
- int i 1
- while (i lt 10)
-
- sum sum i
- i i 1
-
- cout ltlt sum
3
6
sum
ilt10
true
false
sumsumi ii1
coutltltsum
10Walkthrough of the example
10
11
i
- int sum 0
- int i 1
- while (i lt 10)
-
- sum sum i
- i i 1
-
- cout ltlt sum
45
55
sum
ilt10
true
false
sumsumi ii1
coutltltsum
11while loop syntax
-
- ltinitializationgt
- while (lttestgt)
-
- ltstatement1gt
- ...
- ltstatementNgt
- ltupdategt
12while loop sum example
- Sum of numbers from 1..10
- int sum 0
- int i 1
- while (i lt 10)
-
- sum sum i
- i i 1
-
- cout ltlt sum
initialization
test
body statements
update
13Anatomy of a loop
- Initialize variables used in loop body and loop
test (before the loop) - No general rule. The way of initialization and
the initial values are to be determined according
to the application - The loop test is evaluated before each loop
iteration - NOT evaluated after each statement in the loop
body - Current value of variables are used for the loop
test before each iteration - The loop body must update some variables used in
the loop test so that the loop eventually
terminates - If loop test is always true, loop is infinite
- Infinite loops must be avoided
- Basic rule of designing a loop
- Initialization, loop test and update parts should
be designed carefully in order to iterate the
loop as many times as needed, but not one less or
one more. - Unfortunately there is no straightforward rule of
designing a bug-free loop - you should be able to develop those parts by
understanding and analyzing the underlying
problem that needs a loop
14for loop syntax
- for (ltinitializationgt lttestgt ltupdategt)
-
- ltstatement1gt ... ltstatementNgt
-
- Initialization, test and update parts are
combined - Good for counting on an index kind of loops.
15for loop syntax compared with while
- for (ltinitializationgt
- lttestgt
- ltupdategt )
-
- ltstatement1gt ... ltstatementNgt
-
- ltinitializationgt
- while (lttestgt)
-
- ltstatement1gt
- ...
- ltstatementNgt
- ltupdategt
-
16for loop example
- Rewrite the same loop sum of numbers from 1..10
- int sum 0
- for (int i1 i lt 10 ii1)
-
- sum sum i
-
- int sum 0
- int i 1
- while (i lt 10)
-
- sum sum i
- i i 1
-
17The for loop
- initialization statement
- executed once before the loop
- test expression
- boolean expression
- checked each time before entering the loop body
- if true execute loop body, if false terminate
loop - update statement
- executed after the last statement of the loop
body - several statements in initialization and update
are separated by comma - for(len s.length(), k0 k lt len k1)
- initialization and/or test and/or update parts
could be missing - but semicolons are there
18The for loop
- For loops are good for counting loops (although
they can be used for conditional loops) - Number of iterations known before loop begins
- Example sum of 10 input numbers
- Example print a string vertically
- void Vertical(string s)
- // post chars of s printed vertically
- int len int k
- len s.length()
- k 0
- while (k lt len)
-
- cout ltlt s.substr(k,1) ltlt endl
- k 1
-
- // for loop alternative 1 // for loop
alternative 2
// for loop alternative 3 int len int k
len s.length() k 0 for( k lt len k
1) cout ltlt s.substr(k,1) ltlt endl
19Example Print a string backwards (revstring.cpp)
- Determine the index of the last character of the
string, and then access each character backwards - How many times should the loop iterate ?
- string s int k
- cout ltlt "enter string "
- cin gtgt s
- cout ltlt s ltlt " reversed is "
-
- k s.length() - 1 // index of last
character in s - while (k gt 0)
-
- cout ltlt s.substr(k,1)
- k - 1
-
- cout ltlt endl
- What could we use instead of s.substr(k,1) ?
- s.at(k)
20Reverse String as a function
- First step, what is the prototype?
- string revstring(string s)
- // pre s c0c1c2cn-1
- // post return cn-1c2c1c0
- Second step, how do we build a new string?
- Start with an empty string, ""
- Add one character at each iteration using
concatenation, - rev rev s.substr(k,1)
- Use revstring to determine if a string is a
palindrome
21See palindrome.cpp for full program
- string revstring(string s)
- // post returns reverse of s, that is "stab" for
"bats -
- int k s.length() 1
- string rev "" // start with empty
string - while (k gt 0)
-
- rev rev s.substr(k,1)
- k - 1
-
- return rev
-
- bool IsPalindrome(string word)
- // post returns true if and only word is a
palindrome -
- return (word revstring(word))
22Bad loops
- for (int i 10 i lt 5 i)
-
- cout ltlt "How many times do I print?"
-
- for (int i 10 i gt 1 i)
-
- cout ltlt "How many times do I print?"
-
- int i 1
- while (i lt 20)
-
- cout ltlt "How many times do I print?"
-
23Bad loops
- Never executes
- Never stops (infinite loops)
- Example consider the following modified code
from sum10nums - Whats the problem in the loop below? What is
missing? -
- sum 0
- count 1
- while (count lt 10)
-
- cin gtgt num
- sum num
-
- count never reaches 10, because count is not
updated in the loop
24Infinite loops
- Infinite loop is something that must be avoided
- happens when the loop condition is always true
- same loop body iterates forever
- sometimes you see an output, sometimes you dont
- press Ctrl-C to stop
- could be because of a wrong or missing update
statement - could be because of a wrong condition could be
another reason
25Infinite loops
- What is the problem with the code below?
- cannot say infinite loop, depends on input number
- for example, if num is an odd number, then the
loop is infinite -
- cin gtgt num
- int start 0
- while (start ! num)
-
- start 2
- cout ltlt start ltlt endl
-
- How to fix?
- You can check whether num is even before starting
the loop. - if (num 2 0)
- while (start ! num)
- start 2
- cout ltlt start ltlt endl
-
26Other Common Problems
- Easy to iterate one more or one less times
- Test each loop with the inputs that cause
- zero iterations of the loop body
- one iteration of the loop body
- maximum number of iterations
- one less than the maximum number of iterations
- Use the debugger and watch the variables.
27Developing Loops
- Some loops are easy to develop, others are not
- Sometimes the proper loop test and body are hard
to design - Practice helps, but remember
- Good design comes from experience, experience
comes from bad design
28Number Crunching
- Number crunching is a CS term that means a
computing operation that requires several (and
sometimes complex) arithmetic operations - It was the job of early computers
- Numeric Analysis
- classical sub-discipline of computer science
- Today
- implicitly or explicitly, all operations are
numeric - Now we will see some mathematical applications
- factorial calculation
- prime number testing
29Factorial
- n! 1x2xxn is n factorial used in math,
statistics - long factorial(long n)
- // pre 0 lt n
- // post returns n! (1 x 2 x x n)
- Similar to sum, but this time we will calculate a
product within the loop. At the end we will
return the final product. - The loop will iterate n times, multiplying by 1,
2, , n - Suppose we use a variable called product to hold
the result, then product is n! when the loop
terminates. Then we will return it at the end.
30Factorial
- long Factorial(int num)
- // precondition num gt 0
- // postcondition returns num! (1 x 2 x x num)
-
- long product 1
- int count 0
- while (count lt num)
-
- count 1
- product count
-
- return product
-
- Issues
- Why did we use long? What happens if we use int
instead? - What happens if we initialize count to 1?
31Factorial (Contd) Using BigInt class
- What is the problem of the previous program?
- integer overflow
- even long is not sufficient (actually there is no
difference between long and int for 32-bit
computers like ours) - 12! is 479,001,600 so what happens with 13! ?
- The type BigInt, accessible via include
"bigint.h" can be used like an int, but gets as
big as you want it to be - Really arbitrarily large?
- No, limited to computer memory, but computers
most likely run out of time before running out of
memory - Disadvantages of using BigInt compared to int?
- processing speed is lower
- uses up more memory
- Use BigInt if you really need it
- Do not forget to add bigint.cpp to your project,
- BigInt is a Tapestry class
- Download wincode.zip file from http//cs.duke.edu/
csed/tapestry
32Factorial using BigInt class
33Determining if a number is prime
- Prime number is a natural number which has only
two divisors 1 and itself - Some Cryptographic algorithms depend on prime
numbers - Determining if a number is prime must be easy
- Actually factoring a number must be hard
- hard in the sense that it must be
computationally infeasible to factorize in a
reasonable amount of time - RSA Cryptosystem
- Rivest, Shamir, Adleman
- based on the factorization problem of large
numbers - has been utilized by several security products
and services - PGP (Pretty Good Privacy) e-mail security
- WWW security using SSL protocol
- Sophisticated mathematics used for fast
prime-testing, well do basic prime testing - Since our algorithm is based on factorization, it
will be really slow for large numbers
34Determining Primeness (continued)
- 1 is NOT prime, 2 is prime, 3 is prime, 5 is
prime, 17 is prime, 137, 193? - We do not need to check even numbers other than 2
(2 is a special case) - To check 193, divide it by 3, 5, 7, 9, 11, 13
- Note that 14x14 196, so 13 largest potential
factor? - We will use modulus operator to check
divisibility - Well check odd numbers as potential divisors
- Watch out for 2, it is a special case
- How far should we go to check potential divisors?
- up to and including sqrt(number) 1
- If there was a bigger factor, a smaller factor
would exist. And this smaller one must have been
checked before. So we do not need to go beyond
this limit. - 1 is there to make sure that there will be no
problems with precision - See primes.cpp for code
35Primeness Check Details
- Special even number check is added before the
loop to eliminate even numbers to be checked in
the loop - In order to make the code more efficient
- int limit int(sqrt(n) 1)
- To assign a double value to an int, a typecast is
used, to tell the compiler that the loss of
precision is intentional - Make typecasts explicit to tell the compiler you
know what you are doing - Compiler warnings are avoided
- We will see typecast in more detail later
36for loop compared with while
- for (ltinitializationgt
- lttestgt
- ltupdategt )
-
- ltstatement1gt ... ltstatementNgt
-
- ltinitializationgt
- while (lttestgt)
-
- ltstatement1gt
- ...
- ltstatementNgt
- ltupdategt
-
37Example
- Rewrite the while loop of main of primes.cpp
using for
k low while (k lt high) if
(IsPrime(k)) cout ltlt k ltlt endl
numPrimes 1 k 1
for (k low k lt high k 1) if
(IsPrime(k)) cout ltlt k ltlt endl
numPrimes 1
38Shorthand for increment/decrement
- Lots of code requires incrementing a variable by
one - Three methods, using and , using , and using
- effectively they are same
- num num 1
- num 1
- num // post increment
- It is also possible to write num
- pre-increment
- These differ on when the increment is performed,
but this difference doesnt matter when used as
an abbreviation for the statement n 1 in a
single statement - Similarly there are post-decrement (and
pre-decrement) - num num - 1 num - 1 num--
39The do-while loop
- Similar to while loop, but the test is after the
execution of the loop body - The while loop may never execute, do-while loop
executes at least once - ltinitializationgt
- do
-
- ltstatement1gt ... ltstatementNgt
- ltupdategt
- while (ltconditiongt)
- Example Prompt for a number between 0 and 100,
loop until such a number is entered (user should
enter at least one number) - do
-
- cout ltlt "enter number in range 0..100 "
- cin gtgt num
- while (num lt 0 num gt 100 )
Dont forget
40Priming
- Priming reading an initial value before the loop
- do not get confused with prime numbers this is
something else - Problem enter numbers, add them up, stop when -1
entered - int sum 0
- int num
- cin gtgt num // prime the loop
- while (num ! -1)
- sum num
- cin gtgt num
-
- cout ltlt "total " ltlt sum ltlt end
- Code duplication exists here input (and perhaps
prompt) code is repeated before the loop and in
the loop
41Pseudo infinite solution using break
- To avoid repeating code, include it in the body
of the loop only, use a test to break out of the
loop - break statement exits (inner-most) loop
- I dont prefer this kind of loops (Id prefer
code duplication) - Because the loop condition is not clear, hence
prevents readability - Try not to use break in this course
- Save it for later when you develop really
complicated loops - int sum 0
- int num
- while (true) // seemingly infinite loop
- cin gtgt num
- if (num -1)
- break // get out of loop
-
- sum num
-
- cout ltlt "total " ltlt sum ltlt end
42Fence Post Problem
- The problem that occurs when one or more
operations of the loop body are executed one less
then the others. - Example Display integers between 1 and 10
separated by comma - 1,2,3,4,5,6,7,8,9,10
- no comma after 10 no comma before 1.
- for (n1 n lt 10 n)
- cout ltlt n ltlt ","
- Problem comma after 10
- for (n1 n lt 10 n)
- cout ltlt n ltlt ","
-
- cout ltlt n No problem, but code
duplicates - Think of other solutions! (see page 175 of
Tapestry)
43Downward-counting loop
- Calculate n to the power of m nmnxnxxn
- Example 252x2x2x2x232
- int power 1
- int n, m
- cin gtgt n gtgt m
- for (int i m i lt 1 i--)
-
- power power n
-
44Nested loops
- Sometimes one loop occurs in another
- Generating 2-dimensional tabular data
- multiplication table
- Sorting vectors (which will be studied much
later) - Display some geometric figures using character
(or any other character) - display rectangles, triangles
- Although other loops can be nested as well, most
of the time, for loops are used in nested manner
45Nested loops - Example
- Write a function to display a rectangle of stars
(height and width are parameters) - e.g. if height is 4 and width is 7, the output
should look like -
-
-
-
- for (i1 ilt height i)
-
- for (j1 jltwidth j) // inner loop prints
1 line of stars -
- cout ltlt ""
-
- cout ltlt endl // end of line is put to the
end of each line -
46Nested loops - Example
- Write a function to display a perpendicular
isosceles triangle of stars (perpendicular side
length is parameter) - e.g. if side length is 6 , the output should look
like -
-
-
-
-
-
- for (i1 i lt side i)
-
- for (j1 jlti j) // inner loop prints 1
line of stars -
- cout ltlt ""
-
- cout ltlt endl // end of line is put to the
end of each line -
47Same loop downward-counting
- for (i1 i lt side i)
-
- for (j1 jlti j)
-
- cout ltlt ""
-
- cout ltlt endl
-
- for (i1 i lt side i)
-
- for (ji jgt1 j--)
-
- cout ltlt ""
-
- cout ltlt endl
-
48Drawfigures Other Considerations
- What about having a function to display a line of
stars (number of stars is a parameter) - useful for both rectangle and triangle
- void PrintLine (int numstars)
- // pre numstars gt 0
- // post displays numstars stars in one line
-
- int i
- for (i1 ilt numstars i)
- cout ltlt ""
-
- cout ltlt endl // end of line is put to the end
of the line -
- in rectangle function, inner loop is replaced by
a function call - for (i1 iltheight i)
-
- PrintLine(width)
-
49Example Multiplication Table
- On ith line print, i1, i2, i3, ... , ii
- Total number of lines is an input. Display lines
starting with 1. - See multiply.cpp
- include ltiostreamgt
- include ltiomanipgt // for setw
- using namespace std
- int main()
-
- int i,k,numlines
- const int WIDTH 4
- cin gtgt numlines
- for (i1 i lt numlines i)
-
- for (k1 k lt i k)
-
50Constants
- Sometimes very useful
- provides self documentation
- re-use the same value across the program
- avoid accidental value changes
- like variables, but their value is assigned at
declaration and can never change afterwards - declared by using const before the type name (any
type is OK) - const double PI 3.14159
- const string thisclass "CS201"
- const int WIDTH 4
- later you can use their value
- cout ltlt (PI 4 4)
- but cannot change their value
- PI 3.14 causes a syntax error
51Formatting Output
- We use stream manipulator setw to specify the
total number of spaces that the next output will
use - setw(field length)
- written in cout and affects only the next output
value - not the whole cout line
- output is displayed using field length spaces in
right justified manner (any empty space is on the
left) - defined in header file ltiomanipgt, so you have to
have include ltiomanipgt - Example
- cout ltlt setw(9) ltlt "cs201"
- output shown is four blanks and cs201
52Example using robot class (see rectangularscan.cpp
)
- Write a program in which the robot starts at 0,0
and searches a rectangular space that covers nn
cells - n is input (in the example below, n is 8)
- during this journey the robot should pick or put
things on the cells so that all visited cells
occupy one thing