Iteration using for (Part 3)

Early exit from loops

We are now ready to consider some more complex uses of for loops. The following are ways to exit a loop early:

  • Use a return statement inside the loop body.
  • A break statement exits from the loop entirely.
  • A continue statement exits the current iteration of the loop, going to the next iteration.

So far we have seen one possible way to exit a loop early, that is, by using a return statement. A break statement allows the program to exit from the loop and then continue to the rest of the program. If instead we are done with this iteration with the loop but want to go on the next one, we can use a continue statement.

The pseudocode for these statements are break and continue

Revisiting remainder

As an example, let's look at the remainder function again, where we subtract second from first as many times as possible and then return what remains.

When we wrote the function using a "while" loop, we used a condition to determine when to stop: define remainder(first, second) while first >= second first ← first - second return first

To write a "for" loop, we need to figure out how many iterations we might need: define remainder(first, second) result ← first for counter from 1 to first result ← result - second if result < second break return result

For a value of second of at least 1, we cannot subtract second from first more than first times, so the number of iterations will be at most first. As before, we change the value inside the body of the loop and return the result at the end. Notice that we use a new variable instead of first to make it clear that the ending value of the condition has not changed. How do we decide when to exit the loop? Like in the "while" loop, we test the result against second and exit when the result is less than second. Since we introduced a new variable, we ensure that we give it the initial value of first. Is this better than the function using the "while" loop? Think about it - we'll discuss it later.

Example: removing extra blanks

As another example, suppose we wish to create a function that consumes a string and produces the string formed by removing all blank spaces. For example, the string “A bit of ” is to be converted to “Abitof”:

Sample input string:

A

0

1

2

b

3

i

4

t

5

6

o

7

f

8

9

Sample output string:

A

0

b

1

i

2

t

3

o

4

f

5

Writing the function

For loop recipe

  • Express the task as iteration.
  • Specify starting and ending values.

define remove(entry) new ← "" for counter from 0 to length(entry) - 1 if entry[counter] == " " continue new ← new + entry[counter] return new

We use iteration to process each character in order. The starting and ending values will be the first and last indices in the string, namely 0 and one less than the length of the string, length(entry)-1. In each iteration, we'll add the next character to new, except when the character is a blank. Here the continue statement skips the update to new and goes right to the next iteration. Of course we need to give new an initial value, namely the empty string, and return new at the end.

Example: giving different raises to different people

What if we have two sequences to process? Suppose we have two sequences of equal length, one of salaries and one of adjustments to salaries. Each salary in the first sequence is multiplied by the corresponding number in the second sequence to determine the new salary. We want to update the sequence of salaries by iterating through the items in both sequences.

For example, consider the salaries sequence [50, 80, 90, 50, 75, 20, 99, 88, 33, 60] and the adjustments to salaries sequence [1.5, 1, 1, 1.1, 1, 2, 1, 1, 1, 1.1]. The new salary sequence is the first sequence multiplied by the corresponding number in the second sequence, [75, 80, 90, 55, 75, 40, 99, 88, 33, 66]:

Salaries:

50

0

80

1

90

2

50

3

75

4

20

5

99

6

88

7

33

8

60

9

Adjustments to salaries:

1.5

0

1

1

1

2

1.1

3

1

4

2

5

1

6

1

7

1

8

1.1

9

New salaries:

75

0

80

1

90

2

55

3

75

4

40

5

99

6

88

7

33

8

66

9

Writing the function

For loop recipe

  • Express the task as iteration.
  • Specify starting and ending values.

To express the task as iteration, we'll use a counter that keeps track of the index in one of the sequences. Our starting and ending values will be the first and last indices. At each iteration, we update the current entry in the sequence salaries by multiplying the old value by the corresponding value in the sequence boosters. We choose to have our function return the new value of salaries, though this isn't strictly necessary, as the sequence has been change by mutation. define change(salaries, boosters) for counter from 0 to length(salaries) - 1 salaries[counter] ← salaries[counter] * boosters[counter] return salaries

This example demonstrates that we can use a loop to process two sequences at the same time.

Example: counting a character in a sequence of strings

As another example, suppose we have a sequence of strings and a character of interest and we wish to determine the total number of occurrences of the character in all the strings in the sequence. We can use iteration to process each string in turn. To process the characters in a particular string, we can use iteration to process each character.

For example, consider the sequence ["cat", "hippo", "mule", "Ilama", and "fox"]:

"cat"

0

"hippp"

1

"mule"

2

"Ilama"

3

"fox"

9

Using iteration to process each character, we consider in order “c”, “a”, and “t” to complete “cat”. After that, we continue our iteration through strings to consider the next string, namely “hippo”. Again we use iteration to process the characters of hippo, starting with h, continuing to i, and so on.

Writing the function

For loop recipe

  • Express the task as iteration.
  • Specify starting and ending values.

To use iteration on the sequence of strings, our starting and ending values will be the starting and ending indices of the sequence of strings. Then, we use iteration again on a single string such as “cat”. This time, the starting and ending values are the starting and ending indices of a particular string. Notice that the ending value depends on the particular string being processed. It will be 2 when current is “cat” and 4 when current is “hippo”. When processing a particular character in a string, we check if there is a match, and if so increment the count of matches. To complete the function, we need to initialize count and return it at the end. define count_chars(strings, char) count ← 0 for string_count from 0 to length(strings) - 1 current ← strings[string_count] for char_pos from 0 to length(current) - 1 if current[char_pos] == char count ← count + 1 return count

This example demonstrates that loops can be used inside other loops.