LINUX.ORG.RU

C++ сумма элементов двухмерного массива

 


1

5

Такой вопрос. Можно ли как-нибудь красиво и по-функциональному (без циклов) посчитать сумму элементов двумерного вектора? (На C++)

Для одномерного все просто:

s = std::accumulate(v.begin(), v.end(), 0);

А вот с двумерным я не разобрался/не нагуглил

двухмерного массива

Какой класс ты используешь для двумерного массива? Или речь о T[][]?

двумерного вектора

А это ещё что? Если vector<vector<T>>, то тем хуже

Так как у тебя всё-таки выглядит тип данных?

Crocodoom ★★★★★
()

без циклов

нет, нельзя, железка так не работает

красиво

пример почему программисты это низкоквалицированная рабочая сила, которой нужно управлять сверху

anonymous
()
Ответ на: комментарий от yuscompactal

Если у тебя векторы в векторе, то да, нужен вложенный accumulate, как в первом сообщении.

По-хорошему нужно взять нормальный класс двумерного массива, который внутри содержит один непрерывный блок памяти, а не w блоков. И в таком классе всё что тебе нужно будет из коробки.

Да, в std такого класса нет. Может быть он есть в графической либе, с которой ты работаешь с этим canvas.

Crocodoom ★★★★★
()
Ответ на: комментарий от no-such-file

canvas - это просто название, не более. Любые совпадения случайны. Была простенькая задачка, но стало интересно, как еще можно посчитать.

С массивом массивов не поспоришь, да. Так и есть

yuscompactal
() автор топика

Зануда on

Можно ли как-нибудь красиво и по-функциональному (без циклов)
std::accumulate

accumulate это функция с циклом внутри. Пили через рекурсию, тогда будет канонично.

ox55ff ★★★★★
()
Ответ на: комментарий от ox55ff

Не рекурсия не прокатит. Бездарная фп-скриптуха ещё лет 30 назад обделалась с рекурсией. Поэтому по методичке циклы тоже можно. Правда это циклы не называются, но это так всегда у сектантов.

Да и массивов нет, да и функций accumulate не является по методичке. Да и типизации там нет. Да и все его представления о функциональщине - ничего общего с реальностью не имеют. Просто влияние пропаганды.

minihic112
()
Ответ на: комментарий от yuscompactal

Там есть древний valarray - там всё это уже готовое есть. И векторные операции так же есть. Ну и ranges, конечно же.

minihic112
()

красиво и по-функциональному

Как два пальца

https://wandbox.org/permlink/Q5TMCWSKLp4NqeB2

#include "range/v3/view/join.hpp"
#include "range/v3/numeric/accumulate.hpp"

#include <vector>
#include <iostream>

int main() {
  using namespace ranges::v3;

  const std::vector<std::vector<int>> vv = { { 1, 2 }, { 3, 4 }, { 5, 6 } };
  
  const auto sum2d = ranges::accumulate( vv | view::join, 0 );
  std::cout << sum2d << std::endl;

  return 0;
}
voivoid
()
Ответ на: комментарий от minihic112

Бездарная фп-скриптуха ещё лет 30 назад обделалась с рекурсией. Поэтому по методичке циклы тоже можно. Правда это циклы не называются, но это так всегда у сектантов.

По методичке рекурсия превращается в цикл при компиляции

Crocodoom ★★★★★
()
Ответ на: комментарий от Crocodoom

По методичке рекурсия превращается в цикл при компиляции

Не, эта методичка сдохла ещё давно.

minihic112
()
Ответ на: комментарий от voivoid

gcc

#include «range/v3/view/join.hpp»

Это мусорное говно в гцц не нужно. Там почти полностью запилены ренжи.

const std::vector<std::vector<int>> пту

vv = { { 1, 2 }, { 3, 4 }, { 5, 6 } }; Аналогично

const auto sum2d - туда же.

return 0; - ещё дальше.

minihic112
()
Ответ на: комментарий от minihic112

Это мусорное говно в гцц не нужно. Там почти полностью запилены ренжи.

Че? ranges из C++20 это кусок ( хорошо если 1/4 ) ranges-v3 который успели пихнуть в стандарт. Остальное довезут в c++23.

пту

ой-вей

voivoid
()
Ответ на: комментарий от voivoid

Че? ranges из C++20 это кусок

Всё основное там есть. То, что там не запилили каждый алгоритм дерьма - ничего не значит. Обертки делаются одной строчкой.

ranges-v3

Никакой ranges-v3 в стандарт не пихали. Перестаньте повторять эту херню. В стадарт добавили v3-подобный api. А сам api используется везде и всюду, все концепции используемые в нём в С++ были и есть.

Само же ranges-v3 - бездарно сваянное дерьмо. Но то и понятно почему, ведь пилил рядовой, да и пилил как концепт ещё до концептов. Да и всегда это было полигон-помойка. Были предприняты попытки подобавлять концепты, но помогло не особо. Юзабельности не добавилось.

ой-вей

В чём проблема? Какой ещё return 0;, какой ещё птушный const, какой ещё стиль дерьма, какой ещё auto? Ну и убогий говнобокс туда же. Зачем людям показывать дерьмо и учить их дерьму?

minihic112
()
Ответ на: комментарий от minihic112

Не пиши «говно», а пиши «говно, потому что …». Желательно с примерами того, как, по твоему мнению, надо.

Siborgium ★★★★★
()

Можно ли как-нибудь красиво и по-функциональному (без циклов) посчитать сумму элементов двумерного вектора? (На C++)

А зачем? Это всё равно развернется компилятором в цикл, но понятности при этом не прибавится.

SZT ★★★★★
()
Ответ на: комментарий от SZT

понятности при этом не прибавится

Это еще почему? «Дай мне сумму всех элементов» понятнее, чем «Для каждого элемента каждого элемента вектора положи x равным x + e».

Siborgium ★★★★★
()
Ответ на: комментарий от Siborgium

Ну ОК, что по-твоему понятнее, вот это

auto sum = std::accumulate(m.cbegin(), m.cend(), 0, [](auto lhs, const auto& rhs) {
    return std::accumulate(rhs.cbegin(), rhs.cend(), lhs);
});
или это
int sum = 0;
for (int i = 0; i < vect.size(); i++) 
for (int j = 0; j < vect[i].size(); j++)
{
  sum += vect[i][j];
}
?

По-моему второй вариант куда понятней.

SZT ★★★★★
()
Последнее исправление: SZT (всего исправлений: 1)
Ответ на: комментарий от SZT

По-моему второй вариант куда понятней.

А еще лучше без использования векторов.
STL действительно дает много удобств, но они «не бесплатны» /не к тому, что STL плоха/.

Нынешние стандарты C++ похожи на развитие WWW.
Вместо одной строки на Javascript, используют тонны фреймворков /да еще хвалятся своей «крутостью»/.

Владимир

anonymous
()
Ответ на: комментарий от minihic112

напиши как надо. А то вы дошколята только про говно кукарекать можете.

anonymous
()
Ответ на: комментарий от anonymous

Шутка

 INT  pVector;

 INT  sum = 0,
      I   = 1000000,
      J   = 1000000,
      i   = 0,
      j   = 0;

Label01:

 if  ( j < J ) {

  sum += *( (INT *) pVector + i * sizeof( INT ) + j );

  j++;
  goto  Label01;

 } else {
  if  ( i < I ) {

   j = 0;
   i++;
   goto  Label01;

  }

 }

Владимир

anonymous
()
Ответ на: комментарий от anonymous

Шутка

Товарищи ЛОР-овцы! Анонимусы с регистрантами! 
Замучились вы с массивами, запутались в нулях! 
Сидите, разлагаете vector на атомы, 
Забыв, что разлагается картофель на полях. 

Из STL да из плесени бальзам извлечь пытаетесь 
И флудите на форуме по десять раз на дню. 
Ох, вы там добалуетесь! Ох, вы доизвлекаетесь, 
Пока сгниет, заплесневет картофель на корню!

...

Товарищи ЛОР-овцы! Не сумневайтесь, милые:
Коль что у вас не ладится - ну, там, не тот aффект, -
Мы мигом к вам заявимся с Метапрогом и котечкой,
Денечек покумекаем - и выправим дефект.

Владимир

anonymous
()
Ответ на: комментарий от SZT

А по-моему первый. Это

for (int i = 0; i < vect.size(); i++) 
for (int j = 0; j < vect[i].size(); j++)

вообще ни по одному мажорному стайлгайду не пройдет.

Siborgium ★★★★★
()
Ответ на: комментарий от anonymous

Вчера, да и сегодня /день Святого Духа/ праздник.

Слава Святому Господу Отцу Небесному!  
Слава Святому Господу Иисусу Христу!  
Слава Святому Господу Святому Духу!  
Слава ВсеСвятой Владычице Нашей Богородице!
Слава Царице Небесной!  
Слава Царице Милости!  
Слава Святому Животворящему Кресту Господа Нашего!

Владимир

anonymous
()
Ответ на: комментарий от Siborgium

вообще ни по одному мажорному стайлгайду не пройдет.

Не вижу в этом проблемы. Можно сделать по какому-то стайлгайду, если сильно надо. По-моему это намного лучше читается, чем та конструкция, где лямбда внутри std::accumulate

SZT ★★★★★
()
Последнее исправление: SZT (всего исправлений: 2)

А смысл в этом, железно твой компудахтер о лябдах и рекурсии ничего не знает, зато он отлично оперирует циклами, на выходе что через лямбду что через цикл после того как компилятор это все пережует будет одно и тоже плюс минус. Красота - вкусовщина. Но код на циклах бы распарсил любой писака, на лямбдах уже придется лезть смотреть синтаксис лямбд в крестокаше, говно говна идея в общем то про такую вот «красоту», имхо, не осуждаю.

anonymous
()
Ответ на: комментарий от anonymous

Еще чуть-чуть и я слечу в тебе @AntonI

Тот самый Владимир

anonymous
()
Ответ на: комментарий от AntonI

Настоящий программист имеет сильные очки, толстую задницу и не боится условных переходов!(с)

Какая-то дискриминация goto.
Пора митинговать …

Владимир

anonymous
()
Ответ на: комментарий от anonymous

помитингуй, но потом опять на полочку положи, ладно?

Владимир Владимирович.

anonymous
()
Ответ на: комментарий от anonymous

Шутка

Ну что такое while?

Label: …

if ( flLoop ) goto Label;

Вот вам и while …

Владимир

anonymous
()
Ответ на: комментарий от Siborgium

Я написал почему. Что значит как надо? Это ведь очевидные вещи. Тебе непонятно почему эмуляция концептов через хаки - это хуже, чем использование концептов? Как нужно - в ranges из libstdc++.

В общем перечитай ещё раз. Если проще - ranges-v3 - это дырявый концепт. Использование её как либы - задача десятого приоритета.

minihic112
()
Ответ на: комментарий от yuscompactal

Что железка так не работает, это понятно

Работает, если юзать std::execution unseq. Без этого (лично у меня) std::accumulate работает в два раза медленнее (десятки-сотни беззнаковых), чем написанный руками цикл

luntik2012
()
Ответ на: комментарий от voivoid
$ time g++-11.0.0 gcc.cpp -std=gnu++20 -O3 -march=native -fwhole-program

real    0m0,716s
user    0m0,659s
sys     0m0,056s
$ time g++-11.0.0 v3.cpp -std=gnu++20 -O3 -march=native -fwhole-program

real    0m1,154s
user    0m1,082s
sys     0m0,072s

вообще никакой. Совсем.

И то, результаты обусловлены лишь view/join.hpp, когда как в ситуации с libstdc++ - импортируется всё, и в реальности будет импортировано всё. И если мы импортируем view.hpp, который и будет импортирован в реальности - мы получаем уже:

real    0m1,876s
user    0m1,732s
sys     0m0,135s


Дальше - больше. С каждым инстанцированием v3 будет всё в больше и большей жопе. Не говоря о том, что не работает adl.

minihic112
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.