Nie byłem pewien, czy dodawać tę historię, ponieważ nie zakończyła się ona pełnym sukcesem, ale uznałem, że rozwiązanie na to zasługuje. Historia zaczęła się pewnego pięknego środowego popołudnia:
Hej koledzy z #programowanie #cpp Potrzebuje pilnej pomocy ! place jak za króla ;D Pisze własne kolosa mam czas do okooło 18:30 jest do drugi termin 🙁 Tresc zadania
1.Napisac program wykorzystujacy stos, ktory sprawdza czy w danym wyrazeniu nawiasy sa prawidlowo zagniezdzone. Przetestowac dzialanie na wyrazeniu ” [ [ ] [ [ ] [ [ ] ”2.Opracowac rekurnecyjny algorytm pozwalajacy zamienic liczbe dziesietna na liczbe w systemie trojkowym. Sprawdzic dla liczby 123
Liczy na was 5 osob
Rozwiązałem tylko zadanie drugie – na pierwsze zabrakło czasu i pomysłu.
Przede wszystkim, zacznijmy od definicji awangardowej instrukcji retum:
#define retum throw |
Teraz można zabrać się za implementację. Warto trochę pogeneralizować, i utworzyć funkcję pozwalającą ustalać podstawę rozwinięcia:
template<int Base> string to_base(int value) try { to_base_impl<Base>(value); return {}; } catch(return_value rv) { return rv.val; } |
W funkcji to_base_impl można już użyć tercetu try, catch i retum:
template<int Base> void to_base_impl(int value) { try { if(value/Base) to_base_impl<Base>(value/Base); else retum return_value{}; } catch(return_value rv) { rv.val += to_string(value % Base); retum rv; } } |
retum wymaga specjalnego typu zwracanego:
struct return_value : exception { std::string val; char const* what() const noexcept override { return val.c_str(); } }; |
Czyli składając to wszystko do kupy:
#define retum throw struct return_value : exception { std::string val; char const* what() const noexcept override { return val.c_str(); } }; template<int Base> void to_base_impl(int value) { try { if(value/Base) to_base_impl<Base>(value/Base); else retum return_value{}; } catch(return_value rv) { rv.val += to_string(value % Base); retum rv; } } template<int Base> string to_base(int value) try { to_base_impl<Base>(value); return {}; } catch(return_value rv) { return rv.val; } int main() { DBG(to_base<3>(1)); DBG(to_base<3>(2)); DBG(to_base<3>(3)); DBG(to_base<3>(123)); } |
[link]
Zadanie z nawiasami to klasyka informatyki na studiach 😀 Przy otwarciu nawiasu pushujemy na stos, a przy zamknieciu popujemy. Jezeli po zakonczeniu dzialania mamy pusty stos, a w trakcie nie probowalismy pobrac z niego wiecej niz bylo to znaczy, ze wszystko bylo w porzadku 😉
Takie zadania otwarte są dziwne, nie wiadomo jak mają się zakończyć, zrobisz po swojemu, a potem się dowiesz że miało być inaczej tylko nie wiadomo jak, często na rozmowach rekrutacyjnych to stosują, mówię o tym 1 i do tego robisz na czas np: 15 – 20 minut, to z nawiasami jest łatwiejsze to pewnie 5 minut 😉 i nie wiem co to ma udowodnić.
Nie wiem czemu wykładowcy to masochiści i babrają się w tym z C++ jak jest dużo lepszych rozwiązań xD
Nie ma wielu lepszych rozwiązań od C++. Jest po prostu wiele osób, którym nie chce się zagłębić w możliwości jakie daje ten wspaniały język programowania. ; ) Choć porównanie dwóch zbiorów i zwrócenie wszystkich wspólnych elementów prościej jest wykonać skryptem *.py, używając kwargs…