Introduction to Algorithms in PHP
Welcome to Module 12 of our Master PHP from Basics to Advanced series! If you’ve been following along, you’ve mastered PHP basics, OOP, file/database operations, web development, and advanced concepts. Now, it’s time to dive into algorithms in PHP, a critical skill for solving real-world problems efficiently. Algorithms are step-by-step procedures for computations, and mastering them in PHP will enhance your ability to build optimized, scalable applications.In this comprehensive guide, we’ll cover 20+ practical algorithms, including:
1. Prime Number CheckWhat Is a Prime Number?A prime number is a natural number greater than 1 that is divisible only by 1 and itself (e.g., 2, 3, 5, 7).Real-World Example: Coupon Code ValidationIn an e-commerce system, you might use prime numbers to generate unique coupon codes or validate user inputs.Code Example: Basic Prime Number CheckExplanation:Pros:
2. Fibonacci SequenceWhat Is the Fibonacci Sequence?The Fibonacci sequence is a series where each number is the sum of the two preceding ones (e.g., 0, 1, 1, 2, 3, 5, 8).Real-World Example: Financial ForecastingIn a budgeting app, Fibonacci numbers can model growth patterns or sequence-based calculations.Code Example: Iterative FibonacciAdvanced Example: Recursive Fibonacci with MemoizationPros:
3. Factorial CalculationWhat Is Factorial?The factorial of a non-negative integer n is the product of all positive integers up to n (e.g., 5! = 5 × 4 × 3 × 2 × 1 = 120).Real-World Example: Permutation GeneratorIn a scheduling app, factorials calculate possible arrangements of tasks.Code Example: Iterative FactorialAdvanced Example: Recursive FactorialPros:
4. Palindrome CheckWhat Is a Palindrome?A palindrome is a string that reads the same forward and backward (e.g., "radar").Real-World Example: Username ValidationIn a social media app, you might check if usernames are palindromes for uniqueness.Code Example: Palindrome CheckPros:
5. Armstrong NumbersWhat Is an Armstrong Number?An Armstrong number is a number equal to the sum of its digits raised to the power of the number of digits (e.g., 153 = 1³ + 5³ + 3³).Real-World Example: Lottery SystemIn a lottery system, Armstrong numbers might be used for special prize validation.Code Example: Armstrong Number CheckPros:
6. Binary SearchWhat Is Binary Search?Binary search finds an element in a sorted array by repeatedly dividing the search interval in half. It has O(log n) time complexity.Real-World Example: Product SearchIn an e-commerce app, binary search can quickly find a product by ID in a sorted list.Code Example: Binary SearchPros:
7. Linear SearchWhat Is Linear Search?Linear search checks each element in an array until the target is found or the array ends. It has O(n) time complexity.Real-World Example: User LookupIn a small user management system, linear search can find a user by email in an unsorted list.Code Example: Linear SearchPros:
8. Bubble SortWhat Is Bubble Sort?Bubble sort repeatedly steps through the list, compares adjacent elements, and swaps them if they are in the wrong order. It has O(n²) time complexity.Real-World Example: Sorting ProductsIn an e-commerce app, bubble sort can sort products by price for display.Code Example: Bubble SortPros:
9. Selection SortWhat Is Selection Sort?Selection sort divides the array into sorted and unsorted parts, repeatedly selecting the smallest element from the unsorted part and placing it in the sorted part. It has O(n²) time complexity.Real-World Example: Leaderboard RankingIn a gaming app, selection sort can rank players by score.Code Example: Selection SortPros:
10. Insertion SortWhat Is Insertion Sort?Insertion sort builds a sorted array one element at a time, inserting each element into its correct position. It has O(n²) time complexity.Real-World Example: Task SchedulingIn a task app, insertion sort can order tasks by priority.Code Example: Insertion SortPros:
11. Merge SortWhat Is Merge Sort?Merge sort divides the array into halves, recursively sorts them, and merges the sorted halves. It has O(n log n) time complexity.Real-World Example: Report GenerationIn a reporting system, merge sort can sort large datasets of sales data efficiently.Code Example: Merge SortPros:
12. Quick SortWhat Is Quick Sort?Quick sort selects a pivot, partitions the array around it, and recursively sorts the sub-arrays. It has O(n log n) average time complexity.Real-World Example: Inventory SortingIn an inventory system, quick sort can sort products by stock levels.Code Example: Quick SortPros:
13. Counting SortWhat Is Counting Sort?Counting sort uses a count array to sort integers within a specific range, with O(n + k) time complexity (k is the range of values).Real-World Example: Vote CountingIn an election system, counting sort can tally votes efficiently.Code Example: Counting SortPros:
14. Radix SortWhat Is Radix Sort?Radix sort sorts integers by processing individual digits, using counting sort as a subroutine. It has O(nk) time complexity (k is the number of digits).Real-World Example: Sorting Order IDsIn an order management system, radix sort can sort order IDs by digits.Code Example: Radix SortPros:
15. Anagram CheckWhat Is an Anagram?An anagram is a word formed by rearranging the letters of another (e.g., "listen" and "silent").Real-World Example: Word GameIn a word game, an anagram check validates user-submitted words.Code Example: Anagram CheckPros:
16. String ReversalWhat Is String Reversal?String reversal reverses the order of characters in a string (e.g., "hello" becomes "olleh").Real-World Example: Data TransformationIn a text processing app, string reversal can format data or create mirror text effects.Code Example: String ReversalAdvanced Example: Manual ReversalPros:
17. Matrix OperationsWhat Are Matrix Operations?Matrix operations include addition, multiplication, transposition, etc., on 2D arrays representing matrices.Real-World Example: Image ProcessingIn an image editing app, matrices can represent pixel data for transformations.Code Example: Matrix AdditionPros:
18. GCD & LCM CalculationWhat Are GCD and LCM?GCD (Greatest Common Divisor) is the largest number dividing two numbers. LCM (Least Common Multiple) is the smallest multiple of two numbers, calculated as (a * b) / GCD(a, b).Real-World Example: SchedulingIn a task scheduler, GCD and LCM help align task intervals.Code Example: GCD and LCMPros:
19. Tower of HanoiWhat Is Tower of Hanoi?Tower of Hanoi is a recursive puzzle to move disks from one peg to another, following specific rules. It demonstrates recursion.Real-World Example: Task AutomationIn an automation system, Tower of Hanoi can model sequential task dependencies.Code Example: Tower of HanoiPros:
20. Dijkstra’s Algorithm (Graph Shortest Path)What Is Dijkstra’s Algorithm?Dijkstra’s algorithm finds the shortest path in a weighted graph from a source node to all other nodes.Real-World Example: Delivery RoutingIn a delivery app, Dijkstra’s algorithm optimizes routes between locations.Code Example: Dijkstra’s AlgorithmPros:
21. Knapsack Problem (Dynamic Programming)What Is the Knapsack Problem?The Knapsack problem (0/1 version) selects items with maximum value within a weight constraint, using dynamic programming.Real-World Example: Shipping OptimizationIn a logistics app, the Knapsack problem optimizes package selection for a delivery truck.Code Example: Knapsack ProblemPros:
22. Recursion-based AlgorithmsWhat Are Recursion-based Algorithms?Recursion involves functions calling themselves to solve smaller subproblems. Many algorithms (e.g., Fibonacci, Tower of Hanoi) use recursion.Real-World Example: File System TraversalIn a file management app, recursion can list all files in a directory and its subdirectories.Code Example: Recursive Directory TraversalPros:
ConclusionCongratulations on completing Module 12: Algorithms in PHP (20+ Practical Examples)! You’ve learned how to implement:
- Prime Number Check
- Fibonacci Sequence
- Factorial Calculation
- Palindrome Check
- Armstrong Numbers
- Binary Search
- Linear Search
- Bubble Sort
- Selection Sort
- Insertion Sort
- Merge Sort
- Quick Sort
- Counting Sort
- Radix Sort
- Anagram Check
- String Reversal
- Matrix Operations
- GCD & LCM Calculation
- Tower of Hanoi
- Dijkstra’s Algorithm (Graph Shortest Path)
- Knapsack Problem (Dynamic Programming)
- Recursion-based Algorithms
1. Prime Number CheckWhat Is a Prime Number?A prime number is a natural number greater than 1 that is divisible only by 1 and itself (e.g., 2, 3, 5, 7).Real-World Example: Coupon Code ValidationIn an e-commerce system, you might use prime numbers to generate unique coupon codes or validate user inputs.Code Example: Basic Prime Number Check
php
<?php
function isPrime($number) {
if ($number <= 1) {
return false;
}
for ($i = 2; $i <= sqrt($number); $i++) {
if ($number % $i === 0) {
return false;
}
}
return true;
}
try {
$number = 17;
echo "$number is " . (isPrime($number) ? "prime" : "not prime") . ".\n";
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . "\n";
}
?>
- Checks if $number is less than or equal to 1 (not prime).
- Iterates from 2 to the square root of $number to check divisibility.
- Returns true if no divisors are found.
php
<?php
class CouponGenerator {
public function generatePrimeCoupons($limit) {
$primes = [];
for ($i = 2; $i <= $limit; $i++) {
if ($this->isPrime($i)) {
$primes[] = $i;
}
}
return $primes;
}
private function isPrime($number) {
if ($number <= 1) return false;
for ($i = 2; $i <= sqrt($number); $i++) {
if ($number % $i === 0) return false;
}
return true;
}
}
try {
$generator = new CouponGenerator();
$coupons = $generator->generatePrimeCoupons(50);
echo "Prime coupons: " . implode(", ", $coupons) . "\n";
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . "\n";
}
?>
- Efficiency: Using sqrt() reduces iterations.
- Simplicity: Easy to implement and understand.
- Utility: Useful for cryptography or unique ID generation.
- Performance: Can be slow for large numbers.
- Scalability: Inefficient for generating many primes.
- Use sqrt() to optimize divisibility checks.
- Validate inputs to ensure positive integers.
- Cache prime numbers for repeated use.
- Sieve of Eratosthenes: Faster for generating multiple primes (covered later).
2. Fibonacci SequenceWhat Is the Fibonacci Sequence?The Fibonacci sequence is a series where each number is the sum of the two preceding ones (e.g., 0, 1, 1, 2, 3, 5, 8).Real-World Example: Financial ForecastingIn a budgeting app, Fibonacci numbers can model growth patterns or sequence-based calculations.Code Example: Iterative Fibonacci
php
<?php
function fibonacci($n) {
if ($n < 0) throw new InvalidArgumentException("Negative numbers not allowed.");
if ($n <= 1) return $n;
$prev = 0;
$current = 1;
for ($i = 2; $i <= $n; $i++) {
$next = $prev + $current;
$prev = $current;
$current = $next;
}
return $current;
}
try {
echo "Fibonacci(10): " . fibonacci(10) . "\n"; // 55
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . "\n";
}
?>
php
<?php
class FibonacciGenerator {
private $memo = [];
public function fibonacci($n) {
if ($n < 0) throw new InvalidArgumentException("Negative numbers not allowed.");
if ($n <= 1) return $n;
if (isset($this->memo[$n])) {
return $this->memo[$n];
}
$this->memo[$n] = $this->fibonacci($n - 1) + $this->fibonacci($n - 2);
return $this->memo[$n];
}
}
try {
$generator = new FibonacciGenerator();
echo "Fibonacci(10): " . $generator->fibonacci(10) . "\n"; // 55
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . "\n";
}
?>
- Iterative: Fast and memory-efficient.
- Recursive with Memoization: Balances readability and performance.
- Versatility: Applicable in various domains (e.g., finance, UI design).
- Recursive: Slow without memoization for large n.
- Overflow: Large Fibonacci numbers exceed PHP’s integer limits.
- Use iterative or memoized recursive approaches for performance.
- Handle large numbers with GMP or BCMath extensions.
- Validate inputs to prevent negative numbers.
- Dynamic Programming: Store results in an array (similar to memoization).
- Mathematical Formula: Use Binet’s formula for direct calculation (less practical).
3. Factorial CalculationWhat Is Factorial?The factorial of a non-negative integer n is the product of all positive integers up to n (e.g., 5! = 5 × 4 × 3 × 2 × 1 = 120).Real-World Example: Permutation GeneratorIn a scheduling app, factorials calculate possible arrangements of tasks.Code Example: Iterative Factorial
php
<?php
function factorial($n) {
if ($n < 0) throw new InvalidArgumentException("Negative numbers not allowed.");
if ($n <= 1) return 1;
$result = 1;
for ($i = 2; $i <= $n; $i++) {
$result *= $i;
}
return $result;
}
try {
echo "Factorial(5): " . factorial(5) . "\n"; // 120
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . "\n";
}
?>
php
<?php
class PermutationCalculator {
public function factorial($n) {
if ($n < 0) throw new InvalidArgumentException("Negative numbers not allowed.");
if ($n <= 1) return 1;
return $n * $this->factorial($n - 1);
}
}
try {
$calc = new PermutationCalculator();
echo "Factorial(5): " . $calc->factorial(5) . "\n"; // 120
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . "\n";
}
?>
- Simplicity: Easy to implement iteratively or recursively.
- Utility: Useful for combinatorics and permutations.
- Overflow: Large factorials exceed PHP’s integer limits.
- Recursive: Stack overflow for large n without tail recursion.
- Use iterative approach for better performance.
- Handle large numbers with GMP or BCMath.
- Validate inputs to prevent negative numbers.
- Math Libraries: Use GMP for large factorials.
- Approximation: Stirling’s approximation for large n.
4. Palindrome CheckWhat Is a Palindrome?A palindrome is a string that reads the same forward and backward (e.g., "radar").Real-World Example: Username ValidationIn a social media app, you might check if usernames are palindromes for uniqueness.Code Example: Palindrome Check
php
<?php
function isPalindrome($string) {
$clean = strtolower(preg_replace('/[^a-z0-9]/', '', $string));
return $clean === strrev($clean);
}
try {
$string = "A man, a plan, a canal: Panama";
echo "'$string' is " . (isPalindrome($string) ? "a palindrome" : "not a palindrome") . ".\n";
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . "\n";
}
?>
- Simplicity: Easy to implement with string functions.
- Utility: Useful for validation or text analysis.
- Case Sensitivity: Requires normalization (e.g., lowercase).
- Non-Alphanumeric: Needs preprocessing to ignore spaces/punctuation.
- Normalize input (lowercase, remove non-alphanumeric characters).
- Use strrev() for simplicity.
- Handle empty strings or invalid inputs.
- Two-Pointer Method: Compare characters from both ends (more manual).
- Regular Expressions: Less readable for simple palindromes.
5. Armstrong NumbersWhat Is an Armstrong Number?An Armstrong number is a number equal to the sum of its digits raised to the power of the number of digits (e.g., 153 = 1³ + 5³ + 3³).Real-World Example: Lottery SystemIn a lottery system, Armstrong numbers might be used for special prize validation.Code Example: Armstrong Number Check
php
<?php
function isArmstrong($number) {
$digits = str_split($number);
$power = count($digits);
$sum = array_sum(array_map(fn($digit) => $digit ** $power, $digits));
return $sum === (int)$number;
}
try {
$number = 153;
echo "$number is " . (isArmstrong($number) ? "an Armstrong number" : "not an Armstrong number") . ".\n";
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . "\n";
}
?>
- Educational: Teaches digit manipulation and math operations.
- Validation: Useful for specific numeric checks.
- Niche Use: Limited practical applications.
- Performance: Slow for large numbers.
- Convert numbers to strings for easy digit extraction.
- Validate input to ensure non-negative integers.
- Manual Digit Extraction: Use modulo/division (more complex).
- Precomputed Lists: Store known Armstrong numbers for quick lookup.
6. Binary SearchWhat Is Binary Search?Binary search finds an element in a sorted array by repeatedly dividing the search interval in half. It has O(log n) time complexity.Real-World Example: Product SearchIn an e-commerce app, binary search can quickly find a product by ID in a sorted list.Code Example: Binary Search
php
<?php
function binarySearch($arr, $target) {
$left = 0;
$right = count($arr) - 1;
while ($left <= $right) {
$mid = (int)(($left + $right) / 2);
if ($arr[$mid] === $target) {
return $mid;
} elseif ($arr[$mid] < $target) {
$left = $mid + 1;
} else {
$right = $mid - 1;
}
}
return -1;
}
try {
$products = [1, 3, 5, 7, 9];
$target = 5;
$index = binarySearch($products, $target);
echo $index !== -1 ? "Found $target at index $index.\n" : "$target not found.\n";
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . "\n";
}
?>
- Efficiency: O(log n) for sorted arrays.
- Scalability: Ideal for large datasets.
- Requirement: Array must be sorted.
- Complexity: More complex than linear search.
- Ensure the input array is sorted.
- Use recursive or iterative approaches based on readability needs.
- Validate inputs to prevent errors.
- Linear Search: Simpler but O(n) complexity (covered next).
- Hash Tables: O(1) lookup but requires more memory.
7. Linear SearchWhat Is Linear Search?Linear search checks each element in an array until the target is found or the array ends. It has O(n) time complexity.Real-World Example: User LookupIn a small user management system, linear search can find a user by email in an unsorted list.Code Example: Linear Search
php
<?php
function linearSearch($arr, $target) {
foreach ($arr as $index => $value) {
if ($value === $target) {
return $index;
}
}
return -1;
}
try {
$users = ['john@example.com', 'jane@example.com', 'bob@example.com'];
$target = 'jane@example.com';
$index = linearSearch($users, $target);
echo $index !== -1 ? "Found $target at index $index.\n" : "$target not found.\n";
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . "\n";
}
?>
- Simplicity: Easy to implement and understand.
- No Sorting: Works on unsorted data.
- Inefficiency: O(n) time complexity.
- Scalability: Poor for large datasets.
- Use for small or unsorted datasets.
- Combine with early termination for specific use cases.
- Binary Search: Faster for sorted arrays.
- Database Queries: Use SQL for large datasets.
8. Bubble SortWhat Is Bubble Sort?Bubble sort repeatedly steps through the list, compares adjacent elements, and swaps them if they are in the wrong order. It has O(n²) time complexity.Real-World Example: Sorting ProductsIn an e-commerce app, bubble sort can sort products by price for display.Code Example: Bubble Sort
php
<?php
function bubbleSort($arr) {
$n = count($arr);
for ($i = 0; $i < $n - 1; $i++) {
for ($j = 0; $j < $n - $i - 1; $j++) {
if ($arr[$j] > $arr[$j + 1]) {
[$arr[$j], $arr[$j + 1]] = [$arr[$j + 1], $arr[$j]];
}
}
}
return $arr;
}
try {
$prices = [99.99, 49.99, 199.99, 29.99];
$sorted = bubbleSort($prices);
echo "Sorted prices: " . implode(", ", $sorted) . "\n";
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . "\n";
}
?>
- Simplicity: Easy to understand and implement.
- In-Place: Requires no extra memory.
- Inefficiency: O(n²) time complexity.
- Scalability: Poor for large datasets.
- Use for small datasets or educational purposes.
- Optimize by checking if no swaps occur in a pass.
- Quick Sort: Faster average case (covered later).
- Built-in Functions: Use sort() or usort() for practical sorting.
9. Selection SortWhat Is Selection Sort?Selection sort divides the array into sorted and unsorted parts, repeatedly selecting the smallest element from the unsorted part and placing it in the sorted part. It has O(n²) time complexity.Real-World Example: Leaderboard RankingIn a gaming app, selection sort can rank players by score.Code Example: Selection Sort
php
<?php
function selectionSort($arr) {
$n = count($arr);
for ($i = 0; $i < $n - 1; $i++) {
$minIndex = $i;
for ($j = $i + 1; $j < $n; $j++) {
if ($arr[$j] < $arr[$minIndex]) {
$minIndex = $j;
}
}
[$arr[$i], $arr[$minIndex]] = [$arr[$minIndex], $arr[$i]];
}
return $arr;
}
try {
$scores = [100, 50, 200, 75];
$sorted = selectionSort($scores);
echo "Sorted scores: " . implode(", ", $sorted) . "\n";
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . "\n";
}
?>
- Simplicity: Easy to implement.
- In-Place: Minimal memory usage.
- Inefficiency: O(n²) time complexity.
- No Early Termination: Always runs all iterations.
- Use for small datasets or when memory is constrained.
- Combine with validation for empty or single-element arrays.
- Merge Sort: Better for large datasets (covered later).
- PHP’s sort(): Built-in and optimized.
10. Insertion SortWhat Is Insertion Sort?Insertion sort builds a sorted array one element at a time, inserting each element into its correct position. It has O(n²) time complexity.Real-World Example: Task SchedulingIn a task app, insertion sort can order tasks by priority.Code Example: Insertion Sort
php
<?php
function insertionSort($arr) {
$n = count($arr);
for ($i = 1; $i < $n; $i++) {
$key = $arr[$i];
$j = $i - 1;
while ($j >= 0 && $arr[$j] > $key) {
$arr[$j + 1] = $arr[$j];
$j--;
}
$arr[$j + 1] = $key;
}
return $arr;
}
try {
$priorities = [3, 1, 4, 2];
$sorted = insertionSort($priorities);
echo "Sorted priorities: " . implode(", ", $sorted) . "\n";
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . "\n";
}
?>
- Efficiency: Good for small or nearly sorted datasets.
- Stability: Maintains relative order of equal elements.
- Inefficiency: O(n²) for large datasets.
- Complexity: More complex than bubble sort.
- Use for small or partially sorted data.
- Validate input arrays for correctness.
- Quick Sort: Faster for large datasets.
- PHP’s sort(): Built-in and optimized.
11. Merge SortWhat Is Merge Sort?Merge sort divides the array into halves, recursively sorts them, and merges the sorted halves. It has O(n log n) time complexity.Real-World Example: Report GenerationIn a reporting system, merge sort can sort large datasets of sales data efficiently.Code Example: Merge Sort
php
<?php
function mergeSort($arr) {
if (count($arr) <= 1) return $arr;
$mid = (int)(count($arr) / 2);
$left = mergeSort(array_slice($arr, 0, $mid));
$right = mergeSort(array_slice($arr, $mid));
return merge($left, $right);
}
function merge($left, $right) {
$result = [];
$i = $j = 0;
while ($i < count($left) && $j < count($right)) {
if ($left[$i] <= $right[$j]) {
$result[] = $left[$i++];
} else {
$result[] = $right[$j++];
}
}
return array_merge($result, array_slice($left, $i), array_slice($right, $j));
}
try {
$sales = [100, 50, 200, 75];
$sorted = mergeSort($sales);
echo "Sorted sales: " . implode(", ", $sorted) . "\n";
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . "\n";
}
?>
- Efficiency: O(n log n) for all cases.
- Stability: Maintains relative order of equal elements.
- Memory: Requires O(n) extra space.
- Complexity: More complex than simpler sorts.
- Use for large datasets or when stability is needed.
- Optimize by reducing array copies if possible.
- Quick Sort: Faster average case but unstable.
- PHP’s sort(): Built-in and optimized.
12. Quick SortWhat Is Quick Sort?Quick sort selects a pivot, partitions the array around it, and recursively sorts the sub-arrays. It has O(n log n) average time complexity.Real-World Example: Inventory SortingIn an inventory system, quick sort can sort products by stock levels.Code Example: Quick Sort
php
<?php
function quickSort($arr, $low, $high) {
if ($low < $high) {
$pivotIndex = partition($arr, $low, $high);
quickSort($arr, $low, $pivotIndex - 1);
quickSort($arr, $pivotIndex + 1, $high);
}
return $arr;
}
function partition(&$arr, $low, $high) {
$pivot = $arr[$high];
$i = $low - 1;
for ($j = $low; $j < $high; $j++) {
if ($arr[$j] <= $pivot) {
$i++;
[$arr[$i], $arr[$j]] = [$arr[$j], $arr[$i]];
}
}
[$arr[$i + 1], $arr[$high]] = [$arr[$high], $arr[$i + 1]];
return $i + 1;
}
try {
$stock = [10, 5, 20, 8];
$sorted = quickSort($stock, 0, count($stock) - 1);
echo "Sorted stock: " . implode(", ", $sorted) . "\n";
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . "\n";
}
?>
- Efficiency: O(n log n) average case.
- In-Place: Minimal extra memory.
- Worst Case: O(n²) for already sorted or reverse-sorted arrays.
- Instability: Does not maintain relative order of equal elements.
- Choose a good pivot (e.g., median or random).
- Use for large datasets with random data.
- Merge Sort: Stable and predictable but uses more memory.
- PHP’s sort(): Built-in and optimized.
13. Counting SortWhat Is Counting Sort?Counting sort uses a count array to sort integers within a specific range, with O(n + k) time complexity (k is the range of values).Real-World Example: Vote CountingIn an election system, counting sort can tally votes efficiently.Code Example: Counting Sort
php
<?php
function countingSort($arr, $max) {
$count = array_fill(0, $max + 1, 0);
$output = [];
foreach ($arr as $num) {
$count[$num]++;
}
for ($i = 0; $i <= $max; $i++) {
while ($count[$i] > 0) {
$output[] = $i;
$count[$i]--;
}
}
return $output;
}
try {
$votes = [1, 3, 2, 1, 3, 1];
$sorted = countingSort($votes, 3);
echo "Sorted votes: " . implode(", ", $sorted) . "\n";
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . "\n";
}
?>
- Efficiency: O(n + k) for small ranges.
- Stability: Can be made stable with modifications.
- Limited Use: Only works for integers in a known range.
- Memory: Requires extra space for the count array.
- Use for small integer ranges.
- Validate input to ensure non-negative integers.
- Radix Sort: Handles larger ranges (covered next).
- PHP’s sort(): General-purpose sorting.
14. Radix SortWhat Is Radix Sort?Radix sort sorts integers by processing individual digits, using counting sort as a subroutine. It has O(nk) time complexity (k is the number of digits).Real-World Example: Sorting Order IDsIn an order management system, radix sort can sort order IDs by digits.Code Example: Radix Sort
php
<?php
function radixSort($arr) {
$max = max($arr);
for ($exp = 1; $max / $exp > 0; $exp *= 10) {
$arr = countingSortByDigit($arr, $exp);
}
return $arr;
}
function countingSortByDigit($arr, $exp) {
$n = count($arr);
$output = array_fill(0, $n, 0);
$count = array_fill(0, 10, 0);
foreach ($arr as $num) {
$count[($num / $exp) % 10]++;
}
for ($i = 1; $i < 10; $i++) {
$count[$i] += $count[$i - 1];
}
for ($i = $n - 1; $i >= 0; $i--) {
$output[$count[($arr[$i] / $exp) % 10] - 1] = $arr[$i];
$count[($arr[$i] / $exp) % 10]--;
}
return $output;
}
try {
$orderIds = [170, 45, 75, 90, 802, 24, 2, 66];
$sorted = radixSort($orderIds);
echo "Sorted order IDs: " . implode(", ", $sorted) . "\n";
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . "\n";
}
?>
- Efficiency: O(nk) for integer sorting.
- Stability: Maintains relative order of equal elements.
- Complexity: More complex than other sorts.
- Limited Use: Best for integers with fixed digit lengths.
- Use for large datasets of integers.
- Combine with counting sort for each digit.
- Quick Sort: General-purpose and simpler.
- PHP’s sort(): Built-in and optimized.
15. Anagram CheckWhat Is an Anagram?An anagram is a word formed by rearranging the letters of another (e.g., "listen" and "silent").Real-World Example: Word GameIn a word game, an anagram check validates user-submitted words.Code Example: Anagram Check
php
<?php
function isAnagram($str1, $str2) {
$str1 = strtolower(preg_replace('/[^a-z]/', '', $str1));
$str2 = strtolower(preg_replace('/[^a-z]/', '', $str2));
if (strlen($str1) !== strlen($str2)) return false;
$count1 = array_count_values(str_split($str1));
$count2 = array_count_values(str_split($str2));
return $count1 === $count2;
}
try {
$word1 = "listen";
$word2 = "silent";
echo "'$word1' and '$word2' are " . (isAnagram($word1, $word2) ? "anagrams" : "not anagrams") . ".\n";
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . "\n";
}
?>
- Simplicity: Easy to implement with character counts.
- Utility: Useful in games or text analysis.
- Preprocessing: Requires normalization (e.g., lowercase).
- Memory: Uses extra space for character counts.
- Normalize strings (remove spaces, convert to lowercase).
- Use efficient data structures like arrays for counting.
- Sorting Method: Sort both strings and compare (O(n log n)).
- Manual Comparison: Less efficient for large strings.
16. String ReversalWhat Is String Reversal?String reversal reverses the order of characters in a string (e.g., "hello" becomes "olleh").Real-World Example: Data TransformationIn a text processing app, string reversal can format data or create mirror text effects.Code Example: String Reversal
php
<?php
function reverseString($str) {
return strrev($str);
}
try {
$string = "Hello, World!";
echo "Reversed: " . reverseString($string) . "\n";
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . "\n";
}
?>
php
<?php
function manualReverse($str) {
$chars = str_split($str);
$left = 0;
$right = count($chars) - 1;
while ($left < $right) {
[$chars[$left], $chars[$right]] = [$chars[$right], $chars[$left]];
$left++;
$right--;
}
return implode('', $chars);
}
try {
$string = "Hello, World!";
echo "Manually reversed: " . manualReverse($string) . "\n";
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . "\n";
}
?>
- Simplicity: strrev() is built-in and fast.
- Utility: Useful for text manipulation.
- Unicode: strrev() may not handle multibyte strings correctly.
- Manual Method: More complex and slower.
- Use strrev() for simple ASCII strings.
- Use multibyte functions (mb_strrev) for Unicode strings.
- Validate input to handle empty strings.
- Manual Reversal: Two-pointer method for learning purposes.
- Array Reverse: Convert to array and use array_reverse().
17. Matrix OperationsWhat Are Matrix Operations?Matrix operations include addition, multiplication, transposition, etc., on 2D arrays representing matrices.Real-World Example: Image ProcessingIn an image editing app, matrices can represent pixel data for transformations.Code Example: Matrix Addition
php
<?php
function matrixAdd($matrix1, $matrix2) {
$rows = count($matrix1);
$cols = count($matrix1[0]);
if ($rows !== count($matrix2) || $cols !== count($matrix2[0])) {
throw new InvalidArgumentException("Matrices must have same dimensions.");
}
$result = [];
for ($i = 0; $i < $rows; $i++) {
for ($j = 0; $j < $cols; $j++) {
$result[$i][$j] = $matrix1[$i][$j] + $matrix2[$i][$j];
}
}
return $result;
}
try {
$matrix1 = [[1, 2], [3, 4]];
$matrix2 = [[5, 6], [7, 8]];
$result = matrixAdd($matrix1, $matrix2);
echo "Matrix addition:\n";
foreach ($result as $row) {
echo implode(" ", $row) . "\n";
}
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . "\n";
}
?>
- Versatility: Useful in graphics, AI, and data analysis.
- Structured: Matrices are intuitive for 2D data.
- Complexity: Requires careful dimension handling.
- Memory: Large matrices consume significant memory.
- Validate matrix dimensions before operations.
- Use libraries like PHP-ML for advanced operations.
- Libraries: Use PHP-ML or NumPHP for matrix operations.
- Flat Arrays: Less structured but simpler for small tasks.
18. GCD & LCM CalculationWhat Are GCD and LCM?GCD (Greatest Common Divisor) is the largest number dividing two numbers. LCM (Least Common Multiple) is the smallest multiple of two numbers, calculated as (a * b) / GCD(a, b).Real-World Example: SchedulingIn a task scheduler, GCD and LCM help align task intervals.Code Example: GCD and LCM
php
<?php
function gcd($a, $b) {
while ($b !== 0) {
[$a, $b] = [$b, $a % $b];
}
return $a;
}
function lcm($a, $b) {
return abs($a * $b) / gcd($a, $b);
}
try {
$a = 12;
$b = 18;
echo "GCD($a, $b): " . gcd($a, $b) . "\n";
echo "LCM($a, $b): " . lcm($a, $b) . "\n";
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . "\n";
}
?>
- Efficiency: Euclidean algorithm is fast for GCD.
- Utility: Useful in math-heavy applications.
- Limited Use: Niche outside specific domains.
- Edge Cases: Handle zero or negative inputs.
- Use Euclidean algorithm for GCD.
- Validate inputs to avoid division by zero.
- Prime Factorization: Slower but alternative for GCD/LCM.
- Math Libraries: Use GMP for large numbers.
19. Tower of HanoiWhat Is Tower of Hanoi?Tower of Hanoi is a recursive puzzle to move disks from one peg to another, following specific rules. It demonstrates recursion.Real-World Example: Task AutomationIn an automation system, Tower of Hanoi can model sequential task dependencies.Code Example: Tower of Hanoi
php
<?php
function towerOfHanoi($n, $source, $auxiliary, $destination) {
if ($n > 0) {
towerOfHanoi($n - 1, $source, $destination, $auxiliary);
echo "Move disk $n from $source to $destination\n";
towerOfHanoi($n - 1, $auxiliary, $source, $destination);
}
}
try {
towerOfHanoi(3, 'A', 'B', 'C');
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . "\n";
}
?>
- Educational: Teaches recursion clearly.
- Deterministic: Always produces correct moves.
- Complexity: Recursive nature can be hard to grasp.
- Scalability: Slow for large n due to 2^n moves.
- Use recursion for clarity.
- Validate input to ensure positive integers.
- Iterative Solution: Complex and less intuitive.
- Simulation Libraries: Use for visualization.
20. Dijkstra’s Algorithm (Graph Shortest Path)What Is Dijkstra’s Algorithm?Dijkstra’s algorithm finds the shortest path in a weighted graph from a source node to all other nodes.Real-World Example: Delivery RoutingIn a delivery app, Dijkstra’s algorithm optimizes routes between locations.Code Example: Dijkstra’s Algorithm
php
<?php
class Graph {
private $graph;
public function __construct($graph) {
$this->graph = $graph;
}
public function dijkstra($source) {
$dist = array_fill_keys(array_keys($this->graph), INF);
$dist[$source] = 0;
$pq = new SplPriorityQueue();
$pq->insert($source, 0);
while (!$pq->isEmpty()) {
$u = $pq->extract();
foreach ($this->graph[$u] as $v => $weight) {
if ($dist[$u] + $weight < $dist[$v]) {
$dist[$v] = $dist[$u] + $weight;
$pq->insert($v, -$dist[$v]);
}
}
}
return $dist;
}
}
try {
$graph = [
'A' => ['B' => 4, 'C' => 2],
'B' => ['A' => 4, 'D' => 5],
'C' => ['A' => 2, 'D' => 8, 'E' => 10],
'D' => ['B' => 5, 'C' => 8, 'E' => 2],
'E' => ['C' => 10, 'D' => 2]
];
$g = new Graph($graph);
$distances = $g->dijkstra('A');
print_r($distances);
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . "\n";
}
?>
- Accuracy: Finds optimal shortest paths.
- Versatility: Applicable to routing and network problems.
- Complexity: Requires priority queue implementation.
- Limitations: Doesn’t handle negative weights.
- Use a priority queue (e.g., SplPriorityQueue) for efficiency.
- Validate graph structure for correctness.
- Bellman-Ford: Handles negative weights but slower.
- A*: Faster for specific use cases with heuristics.
21. Knapsack Problem (Dynamic Programming)What Is the Knapsack Problem?The Knapsack problem (0/1 version) selects items with maximum value within a weight constraint, using dynamic programming.Real-World Example: Shipping OptimizationIn a logistics app, the Knapsack problem optimizes package selection for a delivery truck.Code Example: Knapsack Problem
php
<?php
function knapsack($values, $weights, $capacity) {
$n = count($values);
$dp = array_fill(0, $n + 1, array_fill(0, $capacity + 1, 0));
for ($i = 1; $i <= $n; $i++) {
for ($w = 0; $w <= $capacity; $w++) {
if ($weights[$i - 1] <= $w) {
$dp[$i][$w] = max($values[$i - 1] + $dp[$i - 1][$w - $weights[$i - 1]], $dp[$i - 1][$w]);
} else {
$dp[$i][$w] = $dp[$i - 1][$w];
}
}
}
return $dp[$n][$capacity];
}
try {
$values = [60, 100, 120];
$weights = [10, 20, 30];
$capacity = 50;
echo "Maximum value: " . knapsack($values, $weights, $capacity) . "\n";
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . "\n";
}
?>
- Optimality: Finds the maximum value solution.
- Versatility: Applicable to resource allocation problems.
- Complexity: O(n * capacity) time and space.
- Scalability: Slow for large capacities.
- Use dynamic programming for efficiency.
- Validate inputs for non-negative values and weights.
- Greedy Approach: Faster but suboptimal for 0/1 knapsack.
- Brute Force: Checks all combinations but exponential time.
22. Recursion-based AlgorithmsWhat Are Recursion-based Algorithms?Recursion involves functions calling themselves to solve smaller subproblems. Many algorithms (e.g., Fibonacci, Tower of Hanoi) use recursion.Real-World Example: File System TraversalIn a file management app, recursion can list all files in a directory and its subdirectories.Code Example: Recursive Directory Traversal
php
<?php
function listFiles($dir) {
$files = [];
$items = scandir($dir);
foreach ($items as $item) {
if ($item === '.' || $item === '..') continue;
$path = "$dir/$item";
if (is_dir($path)) {
$files = array_merge($files, listFiles($path));
} else {
$files[] = $path;
}
}
return $files;
}
try {
$files = listFiles('path/to/directory');
echo "Files:\n" . implode("\n", $files) . "\n";
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . "\n";
}
?>
- Elegance: Simplifies complex problems.
- Readability: Natural for hierarchical problems.
- Performance: Stack overflow for deep recursion.
- Memory: High memory usage for large inputs.
- Use tail recursion or iteration when possible.
- Implement memoization for repeated calculations.
- Set recursion limits in PHP (xdebug.max_nesting_level).
- Iteration: Avoids stack overflow but less elegant.
- Dynamic Programming: Optimizes recursive solutions.
ConclusionCongratulations on completing Module 12: Algorithms in PHP (20+ Practical Examples)! You’ve learned how to implement:
- Prime Number Check, Fibonacci, Factorial, and more for basic computations.
- Binary and Linear Search for efficient data retrieval.
- Bubble, Selection, Insertion, Merge, Quick, Counting, and Radix Sort for sorting data.
- Palindrome, Anagram, and String Reversal for text processing.
- Matrix Operations, GCD/LCM, Tower of Hanoi, Dijkstra’s, and Knapsack for advanced problem-solving.
- Recursion-based Algorithms for hierarchical problems.
0 comments:
Post a Comment