Портирование карты C++ с помощью std:: накапливать на PHP.

Я не очень хорошо разбираюсь в манипулировании массивами в PHP, поэтому у меня простой вопрос переноса. В C++ у меня есть карта std::map<int, int>, для которого неявное упорядочение по ключу является важной частью структуры. Что я хочу сделать, это суммировать все значения для начального диапазона ключей, что я делаю так:

// accumulate helper, since "value_type" is "pair<int, int>"
int pair_adder(int n, const std::map<int, int>::value_type & p) { return n + p.second; }

// To add up values for keys up to N:
int total_value_up_to_time_N(int N)
{
  return std::accumulate(mymap.begin(), mymap.upper_bound(N), 0, pair_adder);
}

Каков был бы идиоматический способ написать эту структуру данных и аккумулятор в PHP?

Чтобы объяснить контекст: структура данных - это простой временной ряд, и я хочу знать, сколько я накопил за раз N, C++ map всегда сортируется по ключу, поэтому я могу добавлять элементы mymap[time] = value; в любом порядке, и карта всегда содержит элементы во временном порядке.

Чтобы объяснить накопление: accumulate Функция суммирует все значения карты, ключи которых не превышают N, Например, возьмите эту карту:

 mymap = { { 1, 20}, {2, 30}, {3, -10}, {4, 15} };

Тогда для N = 2 Я накапливаю 50, для N = 3 Я накапливаю 40, а для N = 12 Я накапливаю 55.


Обновление: я только что понял, что на самом деле нет причин, по которым каждая временная метка должна встречаться только один раз, поэтому структура данных должна быть std::multimap<int, int>, Та же самая функция накопления работает дословно, но если решение PHP требует времени, чтобы быть ключом массива, то это больше не будет работать. Но это не строго важно; Я считаю, что решения, в котором каждый раз требуется быть уникальным, будет достаточно.

3 ответа

Решение

К сожалению, PHP-массив отображает / уменьшает функции только для отображения значений, а не ключей. Если ваша карта использует PHP key => value массивы, вам понадобятся некоторые хитрости, чтобы отфильтровать значения, ключи которых имеют определенное значение. Самым простым является прямой цикл:

$map = array(1 => 20, 2 => 30, 3 => -10, ...);
$n = 3;

$result = 0;
foreach ($map as $key => $value) {
    if ($key <= $n) {
        $result += $value;
    }
}

Отсюда вы можете, конечно, проявить креативность:

$result = array_sum(array_intersect_key(
    $map,
    array_flip(array_filter(array_keys($map), function ($key) use ($n) {
        return $key <= $n;
    }))
));

Или же:

$result = array_sum(array_map(function ($key, $value) use ($n) {
    return $key <= $n ? $value : 0;
}, array_keys($map), $map));

Если вы используете более похожую на C++ карту, которая в PHP была бы массивом массивов, это упрощает проблему:

$map = array(array('key' => 1, 'value' => 20), array(...), ...);

$result = array_reduce($map, function ($v, $m) use ($n) {
    return $v + ($m['key'] <= $n ? $m['value'] : 0);
});

Я не очень знаком с C++, но я постараюсь дать вам краткий обзор массивов в PHP, а затем ответить на ваш вопрос о суммировании.

Каждый массив в PHP можно рассматривать как упорядоченную карту. В отличие от C++, здесь нет ограничений по типу, массив - это просто отображение ключа к значению.

Чтобы создать массив, вы можете использовать следующее:

$arr = array();

Чтобы добавить элементы в массив, есть два способа сделать это. Во-первых, вы можете использовать [] оператор для добавления нового элемента в конец массива. Ключ для этого элемента будет (самый высокий int + 1 ключ), с первым ключом, начинающимся с нуля. Например:

$arr[] = 1;
$arr[] = 2;
$arr[] = 4;

С этой точки зрения, $arr теперь карта со следующими ключами / значениями:

0 => 1
1 => 2
2 => 4

Мы также можем добавить определенные ключи и значения:

$arr[42] = 'cool';
$arr['foo'] = 'bar';

На данный момент карта будет выглядеть следующим образом:

0 => 1
1 => 2
2 => 4
42 => 'cool'
'foo' => 'bar'

В PHP довольно много функций для работы с массивами. Например, есть функции для сортировки массивов (как по ключу и значению, так и определяемыми пользователем способами), объединения массивов, поиска по массивам, применения функций ко всем элементам, сокращения массивов и т. Д. Кроме того, конструкция PHP foreach может быть использован для перебора массива. Используйте это следующим образом:

foreach ($arr as $key => $value) {
    echo 'Value of key ' . $key . ' is ' . $value;
}

Теперь, чтобы ответить на ваш вопрос:

Что я хочу сделать, это суммировать все значения для начального диапазона ключей

Обратите внимание, что если вы добавите значения по порядку, они будут в порядке в массиве. Если это не так, предварительно отсортируйте массив, а затем выполните следующее:

$sum = array_sum(array_slice($arr, 0, $n));

Надеюсь это поможет!

Ну есть array_reduce и карта в основном просто массив. Следовательно:

$result = array_reduce($your_array, function($a, $b) { return $a + $b; });

должен сделать свое дело. Или просто использовать array_sum (спасибо, обожаю)

Другие вопросы по тегам