AP Computer Science A: Selection and Iteration

1. Selection (Decision Structures)

• Definition: Selection controls the flow of execution by choosing between alternative paths based on boolean conditions.

• Key forms in Java:

  - if statement: executes a block when a condition is true.

  - if-else statement: chooses between two alternatives.

  - nested ifs: placing if statements inside others for multi-way decisions.

  - switch statement: multi-branch selection on integer/enum/String (since Java 7).

• Boolean expressions: composed of relational and logical operators; evaluate to true or false.

  - Relational: ==, !=, >, <, >=, <= 

  - Logical: && (and), || (or), ! (not) 

• Short-circuit evaluation:

  - In '&&', if left operand is false, right operand is not evaluated.

  - In '||', if left operand is true, right operand is not evaluated.

  - Use to avoid NullPointerException or expensive computations.

• De Morgan's Laws: useful for simplifying/negating boolean expressions:

!(A && B) (!A) || (!B)
!(A || B)
(!A) && (!B)

• Equality vs. assignment:

  - '==' compares primitive values; for objects, compares references.

  - Use .equals() to compare object contents (e.g., Strings).

• if-else-if ladder vs switch:

  - if-else-if: good for complex boolean conditions.

  - switch: concise for discrete values (int, enum, String).

// if-else example
if (score >= 90) {
    grade = 'A';
} else if (score >= 80) {
    grade = 'B';
} else {
    grade = 'C';
}

// switch example
switch(day) {
    case 1: System.out.println("Mon"); break;
    case 2: System.out.println("Tue"); break;
    default: System.out.println("Other");
}

• Ternary operator (conditional expression): concise single-line selection.

int max = (a > b) ? a : b;

• Best practices for selection:

  - Keep conditions simple and readable.

  - Avoid deep nesting; extract methods when necessary.

  - Validate inputs before using them in conditions (null checks).

• Common pitfalls:

  - Using '=' instead of '==' (assignment vs comparison) — compiler error in Java for primitive in condition.

  - Comparing Strings with '==' instead of .equals().

  - Off-by-one errors in boundary checks.

2. Iteration (Looping Structures)

• Definition: Iteration repeats a block of code while a condition holds or over a collection of elements.

• Loop types in Java:

  - while loop: checks condition before each iteration (entry-controlled).

  - do-while loop: checks condition after iteration (exit-controlled), executes at least once.

  - for loop: compact form with initialization, condition, update; commonly used for counting loops.

  - enhanced for (for-each): iterates over arrays or Iterable collections, read-only access to elements.

// while loop
int i = 0;
while (i < 5) {
    System.out.println(i);
    i++;
}

// do-while loop
int j = 0;
do {
    System.out.println(j);
    j++;
} while (j < 5);

// for loop
for (int k = 0; k < 5; k++) {
    System.out.println(k);
}

// enhanced for (for-each)
int[] arr = {1,2,3};
for (int val : arr) {
    System.out.println(val);
}

• Loop components and patterns:

  - Initialization: set starting state.

  - Condition: controls continuation; must eventually become false for termination.

  - Update: advances state toward termination.

• Common loop patterns:

  - Counter-controlled loop: repeats a known number of times (use for-loop).

  - Sentinel-controlled loop: continues until a special value is read (e.g., -1).

  - Accumulator pattern: sums values during iterations.

  - Search pattern: looks for a value and may break early when found.

// Accumulator example
int sum = 0;
for (int n : nums) {
    sum += n;
}

// Sentinel example (reading input until -1)
int value = scanner.nextInt();
while (value != -1) {
    // process value
    value = scanner.nextInt();
}

• Nested loops: loops inside loops; be careful of time complexity (often O(n^2)).

for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
        // inner work
    }
}

• Loop control statements:

  - break: exits the nearest enclosing loop immediately.

  - continue: skips to next iteration of the loop.

  - return: exits the method (and loop if inside).

• Avoiding infinite loops:

  - Ensure loop condition will become false; update loop variables correctly.

  - Watch for integer overflow and incorrect step directions.

• Off-by-one errors:

  - Common when using '<=' vs '<' or incorrect loop bounds.

  - Verify initial and terminal conditions with small examples.

• Loop invariants and reasoning:

  - Loop invariant: a condition true before and after each iteration; useful for proving correctness.

  - Use invariants to reason about what the loop maintains and ensures.

• Time complexity basics for loops:

  - Single loop over n elements: O(n).

  - Nested loops over n and m: O(n*m).

  - Loops with halving (i = i/2): O(log n).

3. Examples, Tracing, and Common Exam Tasks

• Tracing code: step through execution to determine final variable values or outputs; critical for FRQs.

// Example: trace output
int a = 0;
for (int i = 1; i <= 4; i++) {
    a += i;
}
// After loop, a == 10

• Example: find max in array

int max = arr[0];
for (int i = 1; i < arr.length; i++) {
    if (arr[i] > max) {
        max = arr[i];
    }
}

• Example: count occurrences

int count = 0;
for (int i = 0; i < arr.length; i++) {
    if (arr[i] == target) {
        count++;
    }
}

• Example: remove duplicates (using ArrayList)

ArrayList<Integer> unique = new ArrayList<>();
for (int val : nums) {
    if (!unique.contains(val)) {
        unique.add(val);
    }
}

• Example: using break to exit early

boolean found = false;
for (int i = 0; i < arr.length; i++) {
    if (arr[i] == target) {
        found = true;
        break;
    }
}

• Example: do-while for menu-driven input (executes at least once)

int choice;
do {
    System.out.println("Menu: 1) Add 2) Exit");
    choice = scanner.nextInt();
    if (choice == 1) { /* handle add */ }
} while (choice != 2);

4. Best Practices & AP Exam Strategies

• Write clear, legible code; use meaningful variable names.

• For FRQs, include boundary cases and explain loop termination or invariants when asked.

• When asked to modify loops, show minimal, precise changes (e.g., change condition, update).

• Prefer for-loops for fixed counts and while-loops for sentinel/input-driven loops in FRQs.

• Always consider off-by-one and empty-array edge cases.

• Practice tracing and writing small helper methods to simplify complex selection/iteration logic.

• Know the Java syntax rules: semicolons, braces, and correct method signatures.

5. Quick Reference (Cheat Sheet)

• if (condition) { ... } else { ... }

• switch(value) { case X: ...; break; default: ... }

int i = 0; while (i < n) { ...; i++; }

for (int i = 0; i < n; i++) { ... }

for (Type item : collection) { ... } // enhanced for