Ostatnio szukałem w bibliotekach STL gotowego wzoru Herona (pole trójkąta wyliczone z długości 3 boków). Nie znalazłem więc naszło mnie natchnienie na założenie tego wątku.
Jeżeli ktoś ma jakąś przydatną funkcję w formie template (przyjmuje różne typy zmiennych) i ma chęć podzielenia się ze społecznością to niech wkleja
Naprawdę rozumiem, że STL robi wrażenie, ale to chyba nic dziwnego, że nie zawiera większości algorytmów…
Szczerze mówiąc Twój pomysł jest zły pod każdym względem.
Po pierwsze jakie jest uzasadnienie faktu, że prosty wzór ma być zrealizowany w kodzie na szablonie? Chcesz liczyć pole trójkąta na intach? Ale jeżeli tak to przecież mnożenie 0.5*x czy liczenie sqrt(y) prowadzą do niejawnych konwersji i utraty cyfr, np. 0.5 * (1 + 2 + 4) = 3.
Dlaczego niby masz zwracać zero? A dlaczego nie rzucać wyjątek / logować informację o błędzie / ustawiać flagę błędu / … ?
Co jeżeli jeden lub więcej boków będzie ujemnych? Jeżeli zwrócisz 0 to znaczy że utożsamisz trójkąt zdegenerowany z zupełnie bezsensownymi danymi. Różnica jak między “porządnym” zbiorem, zbiorem pustym a zbiorem wszystkich zbiorów w ZFC.
Co z prawami obliczeń zmiennoprzecinkowych?
ERGO:
C++ pozwala na dużo fajnych rzeczy. Fajnie, że się ich uczysz (templatki są użyteczne). Fajnie, że w ogóle czegoś się uczysz (serio, doceniam). Ale idea templatek NIE polega na tym, że zamiast pisać proste funkcje zaczynasz pisać czary - to jest obfuskowanie kodu. Templatki mają sens gdy np. chcesz stworzyć klasę reprezentującą drzewo i elementy tego drzewa mogą być różnego typu. Wówczas obiekty klasy tworzysz jako obiekty konkretnego typu. Templatki NIE mają sensu jeżeli chcesz stworzyć funkcję, która tak na prawdę w każdym zastosowaniu powinna zostać przemyślana od nowa (bo obliczenia zmiennoprzecinkowe) i właściwie prawie zawsze będzie operować na double.
Dzięki za dobry komentarz. W bardzo dużej części się z tobą zgadzam
Oczywiście funkcja zawsze powinna zwracać double a nie T (już to zmieniłem). Jednak przyjmować jako argumentu może różne typy,
Oczywiście nie trzeba do wszystkiego pisać template.
Dla przykładu który po dałeś 0.5 * (1 + 2 + 4) = 3.akurat funkacja zwróci 0 ponieważ nieda się utwożyć tójkąta (1+2<4) -> 0
Nadrzędną intencją tego wpisu nie był wzór Herona ale zachęcenie aby ktoś się podzielił interesującym/przydatnym template.
Fakt - chodziło mi tylko o efekty działań na intach
A dlaczego nie long double? Albo float? Niemniej fakt, że w tym momencie po prostu się czepiam
Tak. Ale w zastosowaniach może przyjmować long double, float i double. Ale najczęściej będzie to pewnie double. I nigdy nie powinna przyjmować np. inta. Albo stringa.
Sensowne templaty algorytmiczne są w STLu i tam znajdziesz duuużo magii. Pozostałe templaty tego typu są bezsensowne bo tak jak w Twoim przykładzie pokazują, że należy używać funkcji, w ostateczności metod (zwłaszcza przy czasie trwania średniego konkursu). Chyba, że chodzi Ci o jakieś własne próby implementacji części funkcjonalności STLa albo o jakieś własne projekty to wtedy z templatami można i warto się spotkać.
Taka przykładowa sztuczka dla SDLowców z jednego z moich starych pomysłów z wykorzystaniem szablonów
Ja ewentualnie poprawiłbym na przykład jakoś tak jak poniżej
#include <cmath>
/* Szablon obliczanie powierzchni trójkąta wzorem Herona
by neonow79
*/
template <class T, class R>
R PoleTrojkata(T a, T b, T c){
if (a+b < c || a+c < b || b+c < a) return 0; // błędne dane, więc może lepiej return -1
else {
R p = .5*(a+b+c);
return sqrt(p*(p-a)*(p-b)*(p-c));
}
}
To nie takie proste i oczywiste, jak by mogło wyglądać: C++ kruczki i sztuczki
Oczywiście STL to: "The Standard Template Library (STL) is a set of C++ template classes to provide common programming data structures and functions such as …"
Ale uczenie się szablonów jest jednak dużo łatwiejsze z książki do nauki języka C++. Gdybyś zdobył książkę, Algorytmika praktyczna, Piotr Stańczyk, to zobaczyłbyś dużo kodów z praktycznym wykorzystaniem szablonów, ale książka jest już trochę przestarzała. Nie wszystkie kody działają od strzału w najnowszym kompilatorze, makra w C++ odchodzą powoli do lamusa itd…
O ile przez “praktyczne wykorzystanie szablonów” rozumiemy nie nadający się do czytania kod będący połączeniem kilkudziesięciu makr z prostymi szablonami w stylu Graph<typ_wierzcholka, typ_krawedzi>. Jego pomysły mają sens w przypadku zawodowców algorytmiki konkursowej, którzy ćwiczą godzinami (prawie) każdego dnia i szykują się do konkursów klasy światowej. Konkursów, gdzie limity nałożone na wejście są znane. Wspomina o tym zresztą sam autor dając porady dla każdego zespołu.
Gdyby graf to było takie proste coś jak powyżej to byłoby to w STLu. Jeżeli nie jest to istnieje tego przyczyna, np. różne sposoby reprezentowania grafu w pamięci komputera zależą od zastosowania. Zrobienie grafu na templacie ma oczywiście sens jako ćwiczenie, ale czy to przełoży się na realne zastosowania? Na wspomnianych konkursach jest to możliwe, ale w “życiu”?
Z moich największych zabaw z szablonami (głównie różne zrównoważone BST) wyszły same fajne i pouczające zabawki, ale ŻADNA nie była przydatna. Za to klasa BigInt bez szablonów przydała się aż pięć razy na SPOJu. Warto rozumieć kod i tworzyć go na bieżąco adekwatnie do potrzeb. Nie warto szukać magicznego rozwiązania typu “zrobię szablon i będę copy-pastował” bo tak się po prostu zwyczajnie nie da nie licząc tych przypadków, które są już w STLu i kilku innych takich.
Mam nadzieję, że zrozumiałeś i nauczyłeś się co nieco. Nie chcę dalej kontynuować, bo ten dział miał być zbiorem poradników a nie miejscem dyskusji o wyższości świąt wielkanocnych nad … albo o kolorach wiaderek i łopatek. Moja poprawka nadal ma błędy i jeżeli chciałbyś o tym podyskutować, to myślę, że najlepiej zapytaj prywatną pocztą.
Dziękuję za wpisy. Choć na początku zwątpiłem że ten wątek przyniesie coś wartościowego. Teraz dzięki wam nabrał wartości dydaktycznej czyli np pokazał żeby nieprzesadzać z produkcją nowych template oraz pokazał źródła gdzie można dowiedzi się więcej na ten temat.
Moim zdaniem wręcz przeciwnie. Produkuj ich jak najwięcej, programuj korzystając z klas, w końcu to twój czas i to Ty może czegoś nowego się nauczysz lub zmarnujesz go [twój czas]. To zależy co i jak chcesz w przyszłości osiągnąć. Spoj nie wspiera i nie ułatwia programowania z wykorzystaniem własnych bibliotek, czy szablonów ale i nie zabrania. Jednak gdy twoim celem jest znalezienie się jak najwyżej w rankingu, to każdy powie, że to powyżej jest zupełnie bez sensu, i że do rozwiązania większości zadań na Spoju wystarczy “goły” C, a przede wszystkim umiejętność posługiwania się jakąkolwiek internetową wyszukiwarką i odrobina znajomości j.angielskiego, aby szybko znaleźć “gotowca”.
.
.
Każda dobra, aktualna, książka do nauki C++?, do nauki algorytmów i oczywiście Algorytmika praktyczna
PS
Już wkrótce, w super komórce, 4D cloud super duper de Lux, po podaniu odpowiedniego polecenia - numer i nazwa zadania ze spoja - podanym najbezpieczniej w języku angielskim, dostaniesz od razu gotowe rozwiązanie AC. Można będzie porozumiewać się też w rodzimym języku, ale obarczone to będzie oglądaniem dodatkowych reklam google translatora 3D/ver 4902.beta i czasami mogą pojawiać się przekłamania i błędne rozwiązania.
W związku z powyższym, czy warto abyś zawracał sobie głowę i tracił czas, na naukę mało przydatnych i mało praktycznych rzeczy?
Co innego ja, ja nie doczekam tych wspaniałych czasów ;-(, więc muszę sobie jakoś radzić.
Tak samo jak ty mam nadzieję że nie dożyje czarnych czasów które opisujesz
Ja programuje bo sprawia mi to przyjemnośc. Wszystko co wiem nauczyłem się w pół roku. Nic nie uczy lepiej niż pisanie kodu. Współczuje tym którzy wklejają gotowce nabijając ranking.
Zatem jeszcze jeden link, o którym przypomniałem sobie w związku z tym tematem. W rzeczywistości mam jeszcze coś wg mnie wartego uwagi do powiedzenia, ale może za rok, jak znowu będę miał czas na SPOJa. Myślę, że @nenow79 i inni dostali nawet więcej informacji niż chcieli