Портирование карты 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
(спасибо, обожаю)