Code repetition can be accomplished through:
Repetition through loops – use for with start, end condition, and step to repeat code n times
public double bar(double a, double b) {
double result = 0.0;
for (int i = 0; i < b; i++) {
result += a;
}
return result;
}The bar method above calculates a × b (multiplication through repeated addition)
Repetition through loops – use while with an end condition to repeat code until end condition is met
public double baz(double a, double b) {
double result = 0.0;
int i = 0;
while (i < b) {
result += a;
i++;
}
return result;
}The baz method above calculates a × b (multiplication through repeated addition)
Repetition through recursion – function calls itself repeatedly until a specific end condition (base case) is met
public double myRecursiveMethod(double a, double b) {
if (b == 0) return 0.0;
return a + myRecursiveMethod(a, b-1);
}The myRecursiveMethod method above calculates a × b (multiplication through repeated addition)
Let’s trace through with myRecursiveMethod(3.0, 4.0):
Building the stack (going down):
Call 1: myRecursiveMethod(3.0, 4.0)
b == 0? No (b is 4)myRecursiveMethod(3.0, 3.0) ← waits for this resultCall 2: myRecursiveMethod(3.0, 3.0)
b == 0? No (b is 3)myRecursiveMethod(3.0, 2.0)← waits for this resultCall 3: myRecursiveMethod(3.0, 2.0)
b == 0? No (b is 2)myRecursiveMethod(3.0, 1.0) ← waits for this resultCall 4: myRecursiveMethod(3.0, 1.0)
b == 0? No (b is 1)myRecursiveMethod(3.0, 0.0) ← waits for this resultCall 5: myRecursiveMethod(3.0, 0.0)
b == 0? Yes! Base case reachedUnwinding the stack (going up):
Stack: [Call 1, Call 2, Call 3, Call 4]
Stack: [Call 1, Call 2, Call 3]
Stack: [Call 1, Call 2]
Stack: [Call 1]
Stack: [] (empty)
Final result: 12.0
Key: find what is the smaller/simpler version of a problem
StackOverflowError – A stack overflow error occurs when a program attempts to use more memory space in the call stack than what Java allocates
Write a Java class called Factorial with two public methods, both return the factorial of an int argument n:
factorialLoop(int n) – it solves factorial through iterationfactorialRecursion(int n) – it solves factorial through recursionBoth methods should be static – no need for instance variables. Submit your Factorial.java file to gradescope. Test cases: 0! = 1, 5! = 120, 6! = 720
Write two static methods (one with an interative loop and another with recursion) to sum all integers between a and b (inclusive). For a = 3 and b = 5 your methods should compute 3 + 4 + 5 and return 12
Your methods signatures should be:
public static int sumIter(int a, int b)public static int sumRecur(int a, int b)Submit your SumInts.java to gradescope
public class SumInts {
public static int sumIter(int a, int b) {
int total = 0;
while (a <= b) {
total = total + a;
a++;
}
return total;
}
public static int sumRecur(int a, int b) {
if (a > b) return 0;
return a + sumRecur(a + 1, b);
}
public static void main(String[] args) {
System.out.println("sumIter(1, 10) is: " + sumIter(1, 10));
System.out.println("sumRecur(1, 10) is: " + sumRecur(1, 10));
}
}sumIter(1, 3)| line | a<=b | a | total | |
|---|---|---|---|---|
| 1 | 4 | - | 1 | 0 |
| 2 | 5 | true | 1 | 0 |
| 3 | 6 | - | 1 | 1 |
| 4 | 7 | - | 2 | 1 |
| 5 | 5 | true | 2 | 1 |
| 6 | 6 | - | 2 | 3 |
| line | a<=b | a | total | |
|---|---|---|---|---|
| 7 | 7 | - | 3 | 3 |
| 8 | 5 | true | 3 | 3 |
| 9 | 6 | - | 3 | 6 |
| 10 | 7 | - | 4 | 6 |
| 11 | 5 | false | 3 | 3 |
| 12 | 9 | - | 3 | 3 |
sumRecur(1, 3)sumRecur(1, 3) → waits for sumRecur(2, 3) to return
sumRecur(2, 3) → waits for sumRecur(3, 3) to return
sumRecur(3, 3) → waits for sumRecur(4, 3) to return
sumRecur(4, 3) → returns 0
sumRecur(3, 3) → returns 3 + 0 = 3
sumRecur(2, 3) → returns 2 + 3 = 5
sumRecur(1, 3) → returns 1 + 5 = 6
public static int sumRecur(int a, int b, int total)
Write another sumRecur method (Java lets you overload methods), but add an accumulator parameter
sumRecur(int a, int b, int total)total)Call stack example for sumRecur(1, 3, 0):
sum3(1, 3, 0) → sum3(2, 3, 1)
sum3(2, 3, 1) → sum3(3, 3, 3)
sum3(3, 3, 3) → sum3(4, 3, 6)
sum3(4, 3, 6) → returns 6
Java doesn’t guarantee tail call optimization, but the pattern is still more memory-efficient.