LINUX.ORG.RU

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

 


1

5

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

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

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

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

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

Как return 0 связано с концептами

Я нигде не писал, что оно связано с концептами - я писал о том, что оно связано с ПТУ.

при чем тут const auto?

При пту. И проблема не столько в auto, сколько в const. Я не знаю кто(и зачем) научил гениев везде сувать это дерьмо - С++ так не работает.

Если проще, в С++ затирают и пишут всякий мусор в типах не от большого ума. Если откуда-то возвращается const - его нужно сохранить, а если нет - не нужно форфан его менять.

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

Для всего этого есть auto &&, который умеет сам выводить нужный тип, учитывая в том числе и константность.

Если ещё проще. Любое использование const там, где оно не имеет какого-либо смысла(семантического) - пту.

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

Ну в целом я не зря говорил про пту. А потом пацаны спрашивают - действительно ли всё так просто - да, всё так просто. Никакие повадки не берутся из воздуха. Если есть какие-то проблемы в развитии - они проявляются во всём.

И что сейчас мне пишет этот колхозник? В треде уже есть высер колхозника и переделанная на stdc++ ranges версия от fsb. И теперь этот колхозник требует от меня какой-то код, который уже есть.

Да и в целом там нечего сравнивать. Это ещё одна проблема с развитием, когда колхозник приходит и начинает что-то кукарекать. Очевидно, что костыльное дерьмо не будет работать так же быстро, как «нормальная» версия на концептах.

Задача v3 - совместимость, а задача ranges - нормальная работа.

minihic112
()
Ответ на: комментарий от Siborgium
 A return statement (8.7.3) in main has the effect of leaving the main function (destroying any objects with
automatic storage duration) and calling std::exit with the return value as the argument. If control flows
off the end of the compound-statement of main, the effect is equivalent to a return with operand 0 (see also
14.4).

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

Разница не в этом. Это лишь следствие - проявление проблем. Всё это как раз таки говорит о том, понимает ли человек то, что делает. Привычно ли человеку жрать, либо не жрать дерьмо.

Ты не туда смотришь. Ты пытаешься цепляться за какие-то отдельные проявления не думая о том, что к ним привело. И в какой ситуации они будут, а в какой нет.

В данном случае говорилось о красоте. И чего мы хотим? Мы хотим говорить с людьми, которые желают и пониманию то же, что и мы. Но о какой красоте может идти речь, если вкуса у человека нет? Если в одном случае он убрал мусор, а в другом нет?

Это может значить лишь одно. Человеку это не нужно и он ничего в этом не понимает. А всё, что он показал - это просто какой-то трюк, который он где-то увидел.

Но интересно ли нам это? Нет. Потому что у нас есть потребность использовать это везде и всегда и писать так. А у него нет. Значит для него это не более чем трюк, повторю.

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

Тебе такие решения не подходят, такие люди не подходят.

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

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

Твое мышление и риторика - трюк.

Уводить разговор от его темы, чем ты сейчас и занимаешься, затирая в очередной раз свою мозаику устройства мира,в то время как твои душевные переживания никто не спрашивал, и не просил от тебя какого-то анализа о том, кто и что думал. Непонятно с чего ты вообще решил что ты знаешь кто и что думал (еще один твой трюк с подменой и подлогом того кто и что думал и говорил на самом деле), только не начинай пожалуйста свою заунывную копипасту про плебеев.

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

Все это твои трюки - трюки пустобреха, балабола, демагога.

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

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

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

Тут скорее ты желаешь что-то, в чем по факту не разбираешься

Стоит закончить школу и почитать стандарты до того, как что-то так громко вякать. Не знаю, насколько надо быть тупым и неуверенным в себе, чтобы ничего абсолютно не зная по теме, настолько борзо кукарекать. Младшая сестра бьёт? За теребункль дёргает? Ещё мама шнур от монитора отбирает, иначе ты бы хоть что-то знал. Вот так и вырастают безыдейные неграмотные типа-люди, идущие потом в пту в штанишках, которые им купили не на вырост. Идущие зачем? За корочкой. Куда возьмут, туда и идут. В программировании разбираться не нужно, можно пойти в банк или на почту коекакером, эникейщиком или делфи писать.

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

Опять прибежал тот же самый клоун, который пытается нести херню прикрываясь каким-то маня-анализом.

Тут скорее ты желаешь что-то, в чем по факту не разбираешься

По факту ты обделался. Ведь если я в чём-то не разбираюсь, то вперёд - разоблачай меня. Чего сидишь? Это ведь так просто. Но почему-то никто этого не сделал.

Уводить разговор от его темы

Так, трепло, а нука побежало сообщать о том, какая была тема и куда я её увёл.

никто не спрашивал

Как это не спрашивал, если спрашивали. Ты опять обделался. Но что самое важное, чего не спрашивали - так это потуг твоих.

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

Потому что знаю, по праву рождения, которого(права) у тебя нет. Таково уж свойство этой реальности, что все балаболы - это боты. Все они живут по одной методичке, все они - штамповка одного конвейера, жертвы одной и той же пропаганды. Всё их «мышление», все их ответы - шаблонное дерьмо.

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

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

Приходит сектант и сообщает - я бог. Ты ему отвечаешь - ты говно и он начинает блеять херню «ты подменяешь понятия», "вот смотри - там в моей методичке написано - все адепты секты - боги, ты что - споришь с общепринятыми(среди бездарного сектантского сброда) понятиями?

Все это твои трюки - трюки пустобреха, балабола, демагога.

Только вот проблема - ни одного трюка ты не показал. Ты балаболил о том, что они есть. Но не показал. И вопрос - почему? Почему каждый новый бездарный опущенный балабол расскажет тебе, что у тебя что-то есть, но не покажет? Показывай.

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

Маня, ты ссышься мне ответить? Смотрим внимательно. Клоун сообщает, что весь мой анализ - придумки. Что данный клоун - это «пару трюков трепло».

И что же в итоге? Бездарная жертва методички кукарекает шаблонную херню «типа неважно что там return - он же один», при этом на эту чушь уже был дан ответ.

К тому же, return-признак там не один, а один из многих.

А почему балабол себя так ведёт? Потому что методичка ему даёт ответ на «почему написал дерьмо», но не даёт ответа на мои претензии. Потому что его нет. И вот балабол сводит всё к случаю, для которого есть готовый ответ.

Да и ответ сам говно. Уровня «почему ты насрал в углу?» - «да без разницы, ты что постоянно рядом с углами ходишь? Не ходишь, а посреди комнаты я не сру(хотя кого я обманываю)».

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

Нет, не сразу. Если я в коде увижу что-то типа такого

auto sum = std::accumulate(m.cbegin(), m.cend(), 0, [](auto lhs, const auto& rhs) {
    return std::accumulate(rhs.cbegin(), rhs.cend(), lhs);
});

я на пару минут задумаюсь над тем, что это вообще за хрень, и что вообще курил автор. А с циклами у меня таких вопросов не возникнет

SZT ★★★★★
()
Ответ на: комментарий от SZT
int sum = 0;
for (int i = 0; i < vect.size(); i++) 
for (int j = 0; j < vect[i].size(); j++)
{
  sum += vect[i][j];
}

Как можно это было не заметить. Всё прекрасно. Стиль дерьма, инты для счётчиков, счётчики, .size, инкремент из пту. Очевидно, что ничего более понятного быть не может.

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

Вот-вот, обычный цикл, который просто проходит по всем элементам. Без всякой хрени непонятной. int замени на size_t и всё

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

Вместо одной строки на Javascript,

Кресты самый выразительный язык в этом вселенной. Чини методичку.

используют тонны фреймворков /да еще хвалятся своей «крутостью»/.

Это банальная проблема колхозников. Они не в состоянии осознать, что в одной строчке на крестах семантики больше, чем в тысячах на жабаскрипте.

И все эти сложности - это её выражение. То, что ты привык жрать баланду - это не значит, что можно приходить и рассказывать всем, что «зачем вам нужны эти продукты/специи/методики, если можно жрать одну баланду?».

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

Вот-вот, обычный цикл, который просто проходит по всем элементам. Без всякой хрени непонятной. int замени на size_t и всё

Нет, очевидно. Никаким size_t там не отделаешься. Это не кресты. И даже не сишка. Счётчики и там мусор.

Я бы понимал, если бы там показал for(auto && x: vv | join) sum += x;.

Проблемы того кода только в том, что там нет перегрузок для ренжей, которые есть в нормальных крестах. От того он очень замусорен.

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

нормальный класс двумерного массива, который внутри содержит один непрерывный блок памяти, а не w блоков.

[...]

Да, в std такого класса нет.

#include <array>
#include <numeric>
#include <iostream>

int main()
{
	const size_t h = 2;
	const size_t w = 2;
	using row_t = std::array<int, w>;
	std::array<row_t, h> arr{row_t{1,2}, row_t{3,4}};
	auto begin = arr[0].cbegin();
	auto end = arr[h - 1].cend();
	int sum = std::accumulate(begin, end, 0);
	std::cout << sum << "\n";
	return 0;
}
imatveev13
()
Ответ на: комментарий от imatveev13

Это основная проблема крестов. Почему люди их так бояться. Стиль дерьма, код дерьма, костыли дерьма, дерьмо дерьма. Так и живём.

Хотя пацан спрашивал - как жить, как писать красиво. Да, написать длину 10 раз - это круто.

К тому же проблема никуда не уйдёт, как было говно так и останется.

minihic112
()

Ну и да, если пацан хочет «функциональщины»(на самом деле всё это воровано) - ему всего лишь нужно взять нормальные кресты. Можно даже не ваять.

Алгоритмы нужно будет чуть переделать на нормальные, допустим так:

#include <utility>
#include <cstdio>
#include <vector>
#include <numeric>
#include <functional>

template<typename T> concept /*ptu_*/range = requires(T v) {
  std::begin(v);
  std::end(v);
};

namespace std {
  
decltype(auto) accumulate(range auto && v, auto init, auto && op) {
  for(auto && x: v) init = op(x, init);
  return init;
}

decltype(auto) accumulate(range auto && v, auto init) {
  return accumulate(std::forward<decltype(v)>(v), std::move(init), [](auto && a, auto && b) { return a + b; });
}

}

constexpr auto accumulate = [](auto && ... args) -> decltype(auto) { return std::accumulate(std::forward<decltype(args)>(args)...); };

Ну и всё, можно переписывать колхозные варианты вида:

auto sum = std::accumulate(m.cbegin(), m.cend(), 0, [](auto lhs, const auto& rhs) {
    return std::accumulate(rhs.cbegin(), rhs.cend(), lhs);
});

На пацанский:

int main() {
  std::vector vv{std::vector{1, 2}, {3, 4}, {5, 6}};
  
  return accumulate(vv, 0, accumulate);
}

Да, я тут чуть подшаманил поменяв аргументы, но я думаю у труЪ-функциональщика не будет проблем написать функцию реверса аргументов и обернуть ей accumulate. Ну и вместо ptu_range - нужно брать концепты и ranges.

В любом случае, оборачивать алгоритмы нужно. И в лямбду и под ренжи.

В случае с ренжами - достаточно, как уже было сказано -

accumulate(vv | join, 0);

В общем, как жонглировать функциями функциональщики должны понять.

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

Сколько в день новых функций main хэллоувордов пишешь, что тебя аж так наличие return 0; заботит?

Судя по ПО для SpaceX разработано на С++ (комментарий) с признанием «Да и программированием профессионально я занимаюсь редко - это слишком скучно.» наш Царь это Царь хеловордов.

anonymous
()
sum . join $ [[1,2,2],[2,2,1]]
10

Тьі хацкелист? Ану скажи что нибудь на функциональном.

anonymous
()

А об APL еще кто-нибудь помнит?

Владимир

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

но не даёт ответа на мои претензии

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

Поэтому обсуждать твою писанину совершенно контрпродуктивно.

Но вот код это другое дело, тут-то сразу всё и видно.

template<typename T> concept /*ptu_*/range = requires(T v) {
  std::begin(v);
  std::end(v);
};

ADL смотрю не осилил. begin/end может быть и в пользовательском namespace

decltype(auto) accumulate(range auto && v, auto init, auto && op) {
  for(auto && x: v) init = op(x, init);
  return init;
}
  1. Нейтральный элемент ( init ) не мувается в функтор ( op )
  2. x связывается по forwarding reference но при этом не форвардится в функтор
  3. бессмысленные forwarding reference для op и v
  4. нейтральный элемент всегда передается по значению в accumulate, ссылку никак не передать
decltype(auto) accumulate(range auto && v, auto init) {
  return accumulate(std::forward<decltype(v)>(v), std::move(init), [](auto && a, auto && b) { return a + b; });
}

a и b в лямбда-выражении не форвардятся в operator+

Да и вообще только один какой-то дохленький concept с begin/end. Где invokable на op, assignable на init, constraint на operator+

Итог: ты был взвешен, ты был измерен и был признан никуда не годным. Типичный хэлловоурдшик никогда обобщенного кода не писавший

voivoid
()

развели цирк, блин

int foo(const vector<vector<int>>& mat) {
    int sum = 0;
    for (const auto& row: mat) for (int x: row) sum += x;
    return sum;
}

а «красиво и по-функциональному» не нужно, если нет хорошей причины.

Еще и ranges-v3 сюда приплели, лол. Кстати то, что в этой библиотеке под капотом какая-то дичь, в разы замедляющая скорость компиляции - святая правда. Я сам один раз пытался её попробовать, больше не хочу.

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

Дошколёнок решил со мною поиграть, ну давай огрызок.

ADL смотрю не осилил.

char x[123]{}; - исполнять adl, обезьяна. Так же, предоставлять ссылки от тебя, обезьяна, на adl(хотя-бы упоминание). Так же, клоун, оправдываться за это и за то, что до того как я сообщил об adl - ты о нём не кукарекал, ну это относится ко второму пункту.

При чём, что самое удивительное, ведь я заранее говорил об этом. И эта обезьяна явно читала, либо могла прочитать и не обделаться. Но она обделалась.

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

Возможно, он что-то такое имел ввиду:

{
  char x[123]{};
  using std::begin;
  auto i = begin(x);
  ...
}
Как с std::swap. Только насчёт swap эта хрень известная, а про begin/end в таком ракурсе я первый раз слышу. voivoid, какие функции дожны вызываться неквалифицированными обращениями?

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

Не, не это. Очевидно. Эта бездарная обезьяна услышала про adl и решили поумничать. Типа до этого я её в дерьме валял(и оно ничгео не ответило, кстати), а теперь она решила мстить. Но т.к. бездарная - обделалась.

К тому же начала она это кукарекать после того, как я сообщил о том, что v3 adl не работает. Но v3 она лизала жопу. Таким образом её потуга не работает для v3, как и не работает для сишного массива, который не объявлен в std, а begin для него объявлен там. К тому же в для std::begin/end(x) - есть дефолный форвардинг в x.begin/end(). В любом случае всё это неважно. Потому как потуги обезьяны в принципе не состоятельны.

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

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

ok, я не сильно вникал в ваш разговор. А ты сам как считаешь, для каких функций, кроме swap, обращение должно быть без квалификатора?

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

в разы замедляющая скорость компиляции

Время ещё ладно, памяти оно наверно как спирит жрёт, да?

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

А ты сам как считаешь, для каких функций, кроме swap, обращение должно быть без квалификатора?

Никак не считаю. Всё эти рассуждения априори убоги. Это всё попытки заменить понимание на какой-то набор примитивных правил, но это так не работает. Если бы всё можно было свести к этому - никто бы не заморачивался.

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

Подобные рассуждения - это прямо признак бездарности. Для понимания нужны способности и знания, а паре трюков можно научить любую обезьяну. От того обезьяны любят кукарекать о каких-то правилах.

Не нужно за ними повторять.

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

Кстати то, что в этой библиотеке под капотом какая-то дичь, в разы замедляющая скорость компиляции - святая правда.

Там не дичь - там эмуляция концептов на шаблонах и sfinae. И иначе этого не сделаешь, либа писалась тогда, когда реализации концептов не было, а ей они требуются.

а «красиво и по-функциональному» не нужно, если нет хорошей причины.

Это не обобщённый код, это по-сути сишка. Смысл ренжей в том, что-бы его обобщить. Неважно какие типы в векторах, неважно какая вложенность. Неважно какой контейнер, либо его часть, либо какой-то адаптор.

В примитивной херне, конечно же, ничего не нужно. Но в любом случае даже тут join выглядит лучше.

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

что вообще курил автор

Махорку, завёрнутую в учебник Верещагина, очевидно.

я на пару минут задумаюсь

А ты – роскомнадзор.

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

UB, нет? При переходе на следующий row

UB сразу при вызове accumulate с итераторами, не образующими range.

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