главная/Продвинутые алгоритмы обработки данных на PHP
advanced-data-processing-algorithms-php

Продвинутые алгоритмы обработки данных на PHP

В PHP можно использовать различные алгоритмы и структуры данных для решения сложных задач.

Сортировка слиянием (Merge Sort):

Сортировка слиянием — это эффективный алгоритм сортировки, который использует принцип «разделяй и властвуй». Он разбивает массив на две части, сортирует каждую из них и затем сливает их в один отсортированный массив.

function mergeSort(array $array): array
{
    if (count($array) <= 1) {
        return $array;
    }

    $middle = count($array) / 2;
    $left = array_slice($array, 0, $middle);
    $right = array_slice($array, $middle);

    $left = mergeSort($left);
    $right = mergeSort($right);

    return merge($left, $right);
}

function merge(array $left, array $right): array
{
    $result = [];
    $leftIndex = $rightIndex = 0;

    while ($leftIndex < count($left) && $rightIndex < count($right)) {
        if ($left[$leftIndex] < $right[$rightIndex]) {
            $result[] = $left[$leftIndex++];
        } else {
            $result[] = $right[$rightIndex++];
        }
    }

    return array_merge($result, array_slice($left, $leftIndex), array_slice($right, $rightIndex));
}

$array = [5, 2, 1, 7, 6, 8, 4, 3];
$sortedArray = mergeSort($array);
print_r($sortedArray);

Поиск подстроки алгоритмом Кнута-Морриса-Пратта (KMP):

Алгоритм KMP — это эффективный алгоритм поиска подстроки в строке. Он использует префикс-функцию для ускорения поиска.

function kmpSearch(string $text, string $pattern): ?int
{
    $n = strlen($text);
    $m = strlen($pattern);
    $lps = computeLPSArray($pattern, $m);

    $i = $j = 0;
    while ($i < $n) {
        if ($pattern[$j] === $text[$i]) {
            $i++;
            $j++;
        }

        if ($j === $m) {
            return $i - $j;
        } elseif ($i < $n && $pattern[$j] !== $text[$i]) {
            if ($j !== 0) {
                $j = $lps[$j - 1];
            } else {
                $i++;
            }
        }
    }

    return null;
}

function computeLPSArray(string $pattern, int $m): array
{
    $lps = [0];
    $len = 0;
    $i = 1;

    while ($i < $m) {
        if ($pattern[$i] === $pattern[$len]) {
            $len++;
            $lps[$i] = $len;
                  $i++;
        } else {
            if ($len !== 0) {
                $len = $lps[$len - 1];
            } else {
                $lps[$i] = 0;
                $i++;
            }
        }
    }

    return $lps;
}

$text = "ABABDABACDABABCABAB";
$pattern = "ABABCABAB";
$position = kmpSearch($text, $pattern);

if ($position !== null) {
    echo "Pattern found at position: " . $position . PHP_EOL;
} else {
    echo "Pattern not found." . PHP_EOL;
}
   

Дерево отрезков (Segment Tree):

Дерево отрезков — это структура данных, которая используется для выполнения диапазонных запросов и обновлений на массиве.

Оно позволяет выполнять операции, такие как поиск суммы элементов, минимального и максимального значения в заданном диапазоне, эффективно и быстро.

class SegmentTree
{
    private array $tree;
    private int $n;

    public function __construct(array $array)
    {
        $this->n = count($array);
        $this->tree = array_fill(0, 4 * $this->n, 0);
        $this->build($array, 0, 0, $this->n - 1);
    }

    private function build(array &$array, int $index, int $left, int $right)
    {
        if ($left === $right) {
            $this->tree[$index] = $array[$left];
            return;
        }

        $mid = ($left + $right) >> 1;
        $this->build($array, 2 * $index + 1, $left, $mid);
        $this->build($array, 2 * $index + 2, $mid + 1, $right);
        $this->tree[$index] = $this->tree[2 * $index + 1] + $this->tree[2 * $index + 2];
    }

    public function query(int $queryLeft, int $queryRight): int
    {
        return $this->queryHelper(0, 0, $this->n - 1, $queryLeft, $queryRight);
    }

    private function queryHelper(int $index, int $left, int $right, int $queryLeft, int $queryRight): int
    {
        if ($queryLeft <= $left && $right <= $queryRight) {
            return $this->tree[$index];
        }

        if ($queryRight < $left || $right < $queryLeft) {
            return 0;
        }

        $mid = ($left + $right) >> 1;
        return $this->queryHelper(2 * $index + 1, $left, $mid, $queryLeft, $queryRight) +
            $this->queryHelper(2 * $index + 2, $mid + 1, $right, $queryLeft, $queryRight);
    }
}

$array = [1, 2, 3, 4, 5, 6, 7, 8, 9];
$segmentTree = new SegmentTree($array);
$sum = $segmentTree->query(2, 6); // Query the sum of elements from index 2 to 6
echo "The sum of elements from index 2 to 6 is: " . $sum . PHP_EOL;

Динамическое программирование (Dynamic Programming):

Динамическое программирование (DP) — это метод оптимизации алгоритмов, основанный на разбиении задачи на подзадачи, которые решаются однократно, а их результаты сохраняются в таблице для последующего использования.

Это может значительно уменьшить время выполнения некоторых алгоритмов.

Пример алгоритма DP — нахождение чисел Фибоначчи:

function fibonacci(int $n): int
{
    $fib = array_fill(0, $n + 1, 0);
    $fib[1] = 1;

    for ($i = 2; $i <= $n; $i++) {
        $fib[$i] = $fib[$i - 1] + $fib[$i - 2];
    }

    return $fib[$n];
}

$fibonacciNumber = fibonacci(10);
echo "The 10th Fibonacci number is: " . $fibonacciNumber . PHP_EOL;

Поиск кратчайшего пути алгоритмом Дейкстры:

Алгоритм Дейкстры — это алгоритм поиска кратчайшего пути во взвешенном графе с неотрицательными весами ребер.

function dijkstra(array $graph, int $source): array
{
    $distances = array_fill(0, count($graph), INF);
    $distances[$source] = 0;
    $visited = array_fill(0, count($graph), false);

    while (true) {
        $minDistance = INF;
        $minVertex = -1;

        foreach ($distances as $vertex => $distance) {
            if (!$visited[$vertex] && $distance < $minDistance) {
                $minDistance = $distance;
                $minVertex = $vertex;
            }
        }

        if ($minVertex === -1) {
            break;
        }

        $visited[$minVertex] = true;

        foreach ($graph[$minVertex] as $neighbor => $weight) {
            $distances[$neighbor] = min($distances[$neighbor], $distances[$minVertex] + $weight);
        }
    }

    return $distances;
}

$graph = [
    [0, 10, INF, INF, INF, 5],
    [INF, 0, 1, INF, INF, 2],
    [INF, INF, 0, 4, 2, 8],
    [7, INF, 6, 0, INF, INF],
    [INF, INF, 2, INF, 0, 5],
    [INF, 3, 9, 2, INF, 0],
];

$source = 0;
$distances = dijkstra($graph, $source);
echo "Shortest distances from vertex " . $source . " to all other vertices: " . implode(', ', $distances) . PHP_EOL;

Вышеуказанные примеры демонстрируют разнообразие продвинутых алгоритмов обработки данных, которые могут быть реализованы на PHP.