Title: Introducing Loops and Arrays
1Introducing Loops and Arrays
2A Motivational Problem Prime Factors
- Lets assume we need a program that will print
the prime factors of an arbitrary number. - Step 0 The prime factors of a number x are a set
of k numbers (k gt 0) f0, f1fk-1 such that -
- fi is prime for all i 0 lt i ? k
- Step 1 Input information is the number x
- Output is print to screen (a sequence of factors)
- Intermediate the next potential prime factor
3An algorithm
- Find the smallest prime factor, and print it
- Divide the original number by this factor
- Find the prime factors of the quotient
- NOTE all additional prime factors will be at
least as large as the first prime factor. - Question
- How can we find prime factors?
- Well, we can start with 2. Thats prime. And we
can test it. - If 2 doesnt work, well try 3, then try
- 4 isnt prime! How do we know which numbers are
prime?
4Our Algorithm Continued
- Recall our program is required to print the prime
factors. For example, if the input is 24, the
program should print 2 2 2 3. - If we keep dividing by 2, well never have to
worry about 4! - Our program will not make a mistake and think
that a non-prime number is a factor cause well
be dividing out all the small factors first!
5Is That cheating?
- Algorithms are important it pays to stop and
think before committing to code. - In this case, our algorithm is correct, but is it
efficient? - No, not really. We could be dividing by lots of
numbers that are not prime. - But, whats the alternative? Its probably more
expensive (and certainly more complicated) to
single out the prime numbers than it is to just
test all numbers.
6A flow chart
input x
factor 2
factor divides x?
no
yes
x gt 1?
7Literal Translation
- main()
- printf("the prime factors of d are ", x)
- more_factors
- if (x factor 0) // factor divides x
- printf("d ", factor)
- x x / factor
- else
- factor factor 1
-
-
- if (x gt 1) // need to continue?
- goto more_factors
-
-
- printf("\n")
-
8Goto?
- Using goto is about as socially acceptable as
BBQing your neighbors cat. - Why? In non-trivial programs, goto statements
can make the program very hard for a human to
figure out how the program will behave. - There are some special circumstances where goto
is the best way to solve a problem. - but you will probably not encounter a problem
like that in this class - You should expect to lose points if you use goto
9Twisted gotos
- maybe
- if (x 2 0)
- goto maybe_not
-
- printf("x is d\n", x)
- x x 1
- maybe_not
- if (x 2 0)
- x x - 1
- goto done
-
- goto maybe
- done
- if (x gt 2)
- goto maybe_not
-
for what values of x does this program run
forever? Can you tell just by looking at it?
10The while Construct
- The while statement defines a loop.
- When the PC reaches the last statement of the
loop, it will return to the beginning.
loop if (x gt 10) goto done
printf(d , x) x x 1 goto loop done
while (x lt 10) printf(d , x) x x
1
11General form for while
- while (expression)
- / zero or more statements /
-
- If the expression evaluates to true (i.e., not
zero), then the body is executed. - Each time the body is executed the expression is
evaluated again. If the expression still
evaluates to true, the body is executed again.
12Using while for Prime Factors
- main()
- printf("the prime factors of d are ", x)
- while (x gt 1)
- if (x factor 0) // factor divides x
- printf("d ", factor)
- x x / factor
- else // factor does not divide x
- factor factor 1
-
-
- printf("\n")
-
13Style Points for while
- The loop body is contained within
- Put the left on the same line as the
condition - Put the right on a line by itself
- Indent the loop body one tab position
- Do not indent the right
- This is exactly the same formatting we use for
functions (e.g., main) and for if
14Optimizing Prime Factors
- Back to the problem at hand, finding the prime
factors of a number. - Our algorithm is not very efficient.
- Checks even factors (2 is the only even prime)
- Checks factors bigger than sqrt of x
- These are relatively straightforward changes to
make to the algorithm - But, how do we make them in the code?
15Two Ways to Skip Even Factors
- factor 2
- while (x gt 1)
- if (x factor 0)
- printf("d ", factor)
- x x / factor
- else
- if (factor gt 2)
- factor factor 2
- else
- factor factor 1
-
-
-
- while ((x gt 1)
- (x 2) 0)
- printf(2 )
- x x / 2
-
- factor 3
- while (x gt 1)
- if (x factor 0)
- printf("d ", factor)
- x x / factor
- else
- factor factor 2
-
-
16Quitting Early
- We want to stop checking for factors when factor
squared is larger than x. - if ((factor factor) gt x)
- Now what? How do we exit the loop?
- We can use the break statement to break out of
the loop. - while (x gt 1)
- if ((factor factor) gt x)
- break
- // rest of loop
17Complete Program
- / Check if 2 is a factor /
- while ((x gt 1) (x 2) 0)
- printf(d , 2)
- x x / 2
-
- / General case, odd factors /
- factor 3
- while (x gt 1)
- if (x factor 0)
- printf("d ", factor)
- x x / factor
- else
- factor factor 2
-
- if (factor factor gt x) // exhausted all
factors? - printf(d, x)
- break
-
18New Problem, The first 100 Primes Numbers
- Fresh from our success, lets write an efficient
program to print the first 100 prime numbers. - Basic algorithm
- Check all odd numbers to see if theyre prime
- Requires two loops
- Outer loop tries different odd numbers until 100
primes have been found - Inner loop tests a specific odd number to see if
its prime lets write this one first.
19Checking a number for prime
- A number is prime if its only prime factor is
itself. - Let candidate be the number we are checking for
prime, assume we know candidate is odd. - Then, we should try all odd numbers up to the
square root of candidate. - factor 3
- while ((factor factor) lt candidate)
- if ((candidate factor) 0) // not prime
- / ??? /
-
- factor factor 2
20The Outer Loop
- candidate 3
- while (/ lt100 primes printed /)
- / check if candidate is prime /
- if (/ candidate is prime /)
- printf(d , candidate)
-
- candidate candidate 2
-
- Need a couple of extra variables
- num_primes the number of primes printed so far
- was_prime a flag that tells us if the last
candidate was prime. -
21The Whole Program
- num_primes 1 // 2 is the 1st prime
- candidate 3
- while (num_primes lt 100)
- was_prime 1 // we think its prime for now
- factor 3
- while (factor factor lt candidate)
- if ((candidate factor) 0)
- was_prime 0 // definitely composite
- break // no point continuing inner loop
-
- factor factor 2
- // this loop can end for two reasons
- if (was_prime)
- printf(d , candidate)
- num_primes num_primes 1
-
- candidate candidate 2
22Comments on Prime Program
- Nice little program with some sophisticated stuff
going on - Nested loops
- Inner loop can terminate for two reasons
- factor gets too big (the while condition becomes
false) - candidate is proven composite (break statement)
- Our algorithm is not very efficient
- Sieve of Eratosthenes is essentially the same,
except only prime numbers are used for factor. - How can we restrict factor to only the prime
numbers?
23The Need for Arrays
- Sieve of Eratosthenes without arrays
- define 100 different variables p1, p2 p100 each
one holding a different prime. - When evaluating candidate try each pi in turn.
- No way to write this in a loop!
- An array is nothing more than a collection of
variables e.g., int p100 - The collection is named p.
- The first variable is named p0, then p1, etc.
up to p99. NOTE there is no variable
p100!!! - The index can be any arbitrary expression,
e.g., pi
24Using the Array for the Inner Loop
- With the array, we can directly program the Sieve
of Eratosthenes - int i 0 // next prime to check
- while (pi pi lt candidate)
- if (candidate pi 0)
- was_prime 0 // composite
- break // leave the inner loop
-
- i i 1
25Adding new Primes to the array
- When we create the array, we create 100 different
variables. We can assign them just like we do
regular variables. - The outer loop and num_primes tells us how many
primes weve found hence, how many variables in
the array have been assigned! - if (was_prime)
- printf(d , candidate)
- pnum_primes candidate
- num_primes num_primes 1
-
- Note the order, assign pnum_primes before
incrementing num_primes! -
26Summary on Arrays
- Arrays are just collections of variables.
- When we create the array, we must specify the
number of variables we want, e.g., int xn - The n variables are named x0 up to xn-1.
- You can use the variables like any other
variable. - The index expression can be anything that
evaluates to an int between 0 and n-1. - Be careful not to use xn
- Recall C is a loaded gun, try not to point it at
your head - Well come back and explore how arrays work (and
why theyre so dangerous) later.