Minimum/maksimum wielowymiarowego kontenera

Minimum/maksimum wielowymiarowego kontenera
Althorion
Moderator C/C++
  • Rejestracja:prawie 10 lat
  • Ostatnio:około 14 godzin
  • Postów:1605
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…)?

kq
Moderator C/C++
  • Rejestracja:prawie 12 lat
  • Ostatnio:około 21 godzin
  • Lokalizacja:Szczecin
3

Szybkie google sugeruje coś takiego:

Kopiuj
#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


edytowany 1x, ostatnio: kq
Zobacz pozostałe 2 komentarze
kq
To podobne, tylko bardziej wyrafinowane, podejście do mojego stąd: https://dsp.krzaq.cc/post/98/prosty-widok-na-macierz-2d-w-cpp/
Althorion
Ale podaję przy deklaracji multi_array, więc jak to tworzę z czegoś, to muszę wiedzieć z czego, przynajmniej z dokładnością do rozmiaru (żaden problem) i głębokości (irytujące…). Chyba że zaś czegoś nie widzę, a to byłby znak, że czas spać i wrócić do tego jutro…
kq
Ach, to chyba bez type erasure się nie da... W doku MultiArray widziałem funkcję reshape, która może pozwalać na taką konwersję, ale jawną.
Althorion
MultiDimGrid wygląda słodko, ale jest bezlicencyjny i beztestowy… Przejrzę jednak jutro jego implementację i może mnie to zainspiruje.
kq
O, fajnie to wygląda, podoba mi się motyw z op[]
vpiotr
  • Rejestracja:ponad 13 lat
  • Ostatnio:prawie 3 lata
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.

Kopiuj
#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

MarekR22
makra i kod w stylu C? Nie dziękuję.
MarekR22
Moderator C/C++
  • Rejestracja:około 17 lat
  • Ostatnio:minuta
2

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

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

Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.