Minimum/maksimum wielowymiarowego kontenera

1

(kod wrzucę jeśli uznacie, że jest do czegoś potrzebny, ale pytanie mam raczej ogólne)

Bawię się ostatnio biblioteką RapidCheck (z grubsza odpowiednik haskellowego QuickChecka czy pythonowego Hypothesis) i żeby nie musieć myśleć nad problemami, wziąłem sobie zadania z innego tematu.

I tak sobie klepię rozwiązanie, klepię testy, patrzę jak fajnie działa, aż doszedłem do zadania 5.:

Napisz program, który wyszuka i wyświetli na ekranie maksymalny element tablicy 3 x 3.

I tu drobny problem. Piszę to tak ogólnie jak tylko mogę, nie zakładając ani rozmiaru, ani typu kontenera i wykorzystując bibliotekę standardową gdzie tylko mogę i żadne rozwiązanie, które mi przychodzi na myśl, mi się nie podoba:

  1. Ręcznie iterować przez kontener i pod-kontener? Trochę taki XX wiek…
  2. std::max_element dla każdego z pod-kontenerów i potem jeszcze raz dla wyników? Brzydkie…
  3. Własny iterator, co by przebiegał wszystkie elementy? Tyle samo klepania, jak nie więcej, jak w punkcie pierwszym…
  4. boost::multi_array? Też nie ma „płaskich” iteratorów (w sensie .begin() do „lewego górnego” elementu i .end() do „prawego dolnego” i żeby leciał po kolei)…

Jest może jakaś łatwa metoda, żeby „spłaszczyć” kolekcję kolekcji? Albo jakaś popularna biblioteka z liberalną licencją, żeby w razie czego takie coś brać? A może jest jakieś ładne rozwiązanie bez takich kombinacji, którego nie dostrzegam (jestem już po trzecim piwie…)?

3

Szybkie google sugeruje coś takiego:

#include "all.hpp"

#include <boost/multi_array.hpp>

auto main() -> int
{
    boost::multi_array<double, 2> x(boost::extents[2][2]);
    x[0][0] = 1;
    x[0][1] = 2;
    x[1][0] = 33;
    x[1][1] = 4;
    
    auto it = std::max_element(x.origin(), x.origin() + x.num_elements());
    DBG(*it);
}

https://wandbox.org/permlink/6gFv8a6O8dpBYxnQ

0

Moje rozwiązanie na licencji MIT dla zadania:

Napisz program, który wyszuka i wyświetli na ekranie maksymalny element tablicy 3 x 3.

#include <iostream>
#include <algorithm>
#define dim(a,b) ((a)*(b))
#define row(a,b,c) a,b,c
#define at(arr,a,b) arr[a*3+b]
using namespace std;

int main() {
	int arr[dim(3,3)] = {
		row(1,2,31),
		row(3,5,6),
		row(7,1,0)
	};
	int max = *max_element(begin(arr), end(arr));
	cout << "Max: " << max << endl;
	cout << "At: " << at(arr, 0, 2) << endl;
	return 0;
}

https://ideone.com/cQFdGc

2

C++ ranges:
https://wandbox.org/permlink/HtFcht1Pu6z8eCFp

    std::array<std::array<int, 2>, 2> tab {{ {{ 1, 2 }}, {{4, 5}} }};
    auto result = ranges::max(tab | ranges::views::join);
    std::cout << result << '\n';

1 użytkowników online, w tym zalogowanych: 0, gości: 1