Second Opinion
Folosind serviciul second opinion ne puteți trimite RMN-uri, CT -uri, angiografii, fișiere .pdf, documente medicale. Astfel vă vom putea da o opinie neurochirurgicală, fără ca aceasta să poată înlocui un consult de specialitate. Răspunsurile vor fi date prin e-mail în cel mai scurt timp posibil (de obicei în mai putin de 24 de ore, dar nu mai mult de 48 de ore). Second opinion – Neurohope este un serviciu gratuit. www.neurohope.ro |
Generatori
Last Updated: Oct 26 2016 11:01, Started by
dani.user
, Oct 26 2016 11:01
·
0
#1
Posted 26 October 2016 - 11:01
Sa propun azi o abordare ce ajuta la rezolvarea multor feluri de probleme: generators.
Cum putem itera un vector? Daca avem un vector de intregi, una din cele mai intalnite modalitati de a itera prin el (pentru a afisa, de exemplu, valorile pe ecran) arata cam asa: int valori[] = { 1, 2, 3, 4, 5 }; for (int i = 0; i < 5; ++i) { int valoare = valori[i]; std::cout << valoare << " "; } E insa singura modalitate? Nu Cei ce au inteles pointerii se vor gandi probabil la o solutie de genul asta: int valori[] = { 1, 2, 3, 4, 5 }; int* pointer_valoare_curenta = valori; int* sfarsit_valori = valori + 5; //pointer spre primul element de dupa sfarsitul vectorului while (pointer_valoare_curenta != sfarsit_valori) { int valoare = *pointer_valoare_curenta; ++pointer_valoare_curenta; //avanseaza la urmatoarea valoare std::cout << valoare << " "; } Aceasta abordare ajuta mult deoarece:
Abordarea este atat de populara incat biblioteca standard a C++ ofera o gramada de algoritmi care folosesc aceasta abordare de a parcurge o structura de date. De exemplu, suma tuturor elementelor din vector se poate calcula foarte usor asa: int valori[] = { 1, 2, 3, 4, 5 }; int suma = std::accumulate(valori, valori + 5, 0); std::cout << "Suma(valori) = " << suma; Vrem doar suma a doua elemente incepand cu al doilea? Nici o problema: int valori[] = { 1, 2, 3, 4, 5 }; int suma = std::accumulate(valori + 1, valori + 3, 0); std::cout << "Suma(valori) = " << suma; Ce-i un iterator? Ce-i un iterator in C++? Un obiect care se comparta ca un pointer de mai sus. Ne ofera valoarea curenta, stie avansa la urmatoarea (sau precedenta), suporta comparatie cu alt iterator. Asadar, daca schimbam vectorul clasic de mai sus cu unul din STL, putem repeta operatiile de mai sus intr-un mod aproape identic, doarece vectorul ne ofera iteratori. std::vector<int> valori = { 1, 2, 3, 4, 5 }; std::vector<int>::iterator iterator = valori.begin(); std::vector<int>::iterator iterator_sfarsit = valori.end(); while (iterator != iterator_sfarsit) { int valoare = *iterator; ++iterator; std::cout << valoare << " "; } std::vector<int> valori = { 1, 2, 3, 4, 5 }; int suma = std::accumulate(valori.begin() + 1, valori.begin() + 3, 0); std::cout << "Suma(valori) = " << suma; std::vector<int> valori = { 1, 2, 3, 4, 5 }; int suma = std::accumulate(valori.begin(), valori.end(), 0); std::cout << "Suma(valori) = " << suma; Ziceam mai sus ca solutia se poate generaliza. Daca am folosi o lista inlantuita s-ar schimba ceva? Aproape nimic. std::list<int> valori = { 1, 2, 3, 4, 5 }; std::list<int>::iterator iterator = valori.begin(); std::list<int>::iterator iterator_sfarsit = valori.end(); while (iterator != iterator_sfarsit) { int valoare = *iterator; ++iterator; std::cout << valoare << " "; } std::list<int> valori = { 1, 2, 3, 4, 5 }; int suma = std::accumulate(valori.begin() + 1, valori.begin() + 3, 0); std::cout << "Suma(valori) = " << suma; std::list<int> valori = { 1, 2, 3, 4, 5 }; int suma = std::accumulate(valori.begin(), valori.end(), 0); std::cout << "Suma(valori) = " << suma; Ce-i un generator? Daca am avea un vector cu toate elementele de la 1 la 1000, am putea foarte usor folosi iteratori pentru a-l parcurge. Dar a numara de la 1 la 1000 e ceva trivial, de ce ar trebui sa umplu memoria cu toate valorile pentru asa ceva? Aici intervine un generator: un iterator mai special ce iti genereaza pe loc valoarea curenta, n-o citeste pur si simplu dintr-o colectie. La ce ar putea ajuta un astfel de generator? De exemplu la obtinerea sirului lui Fibonacci. Daca am dori sa iteram pe rand valorile sirului, beneficiam de avantaje din ambele directii:
class FibonacciGenerator { public: //instiintam algoritmii ca e un iterator ce stie merge doar inainte, cate un pas odata typedef std::input_iterator_tag iterator_category; typedef uint64_t value_type; typedef uint64_t* pointer; typedef uint64_t* reference; FibonacciGenerator() { currentIndex = 0; //primele doua valori sunt fixate lastValues[0] = 0; lastValues[1] = 1; } static FibonacciGenerator FibonacciGenerator::end() { //returnam un iterator de dupa finalul sirului; //sirul e infinit, insa folosind uint64_t incap doar vreo 93 elemente FibonacciGenerator result; result.currentIndex = 100; return result; } uint64_t operator*() const { //daca suntem la primul sau al doilea element, returnam valorile fixate //atfel returnam suma ultimelor doua valori if (currentIndex == 0) { return lastValues[0]; } if (currentIndex == 1) { return lastValues[1]; } return lastValues[0] + lastValues[1]; } bool operator==(const FibonacciGenerator& other) const { return currentIndex == other.currentIndex; } bool operator!=(const FibonacciGenerator& other) const { return ! (*this == other); } FibonacciGenerator& operator++() { currentIndex += 1; if (currentIndex > 2) { uint64_t currentValue = **this; lastValues[0] = lastValues[1]; lastValues[1] = currentValue; } return *this; } FibonacciGenerator operator++(int) { FibonacciGenerator temp = *this; ++*this; return temp; } private: //tinem minte precedentele doua valori uint64_t lastValues[2]; //la al catelea element din sir am ajuns uint64_t currentIndex; }; Vrem sa afisam primele 50 elemente? Nimic mai simplu FibonacciGenerator fibonacci; for (size_t i = 0; i < 50; i++) { std::cout << "Fibonacci(" << i + 1 << ") = " << *fibonacci++ << "\n"; } Quote
Fibonacci(1) = 0 Fibonacci(2) = 1 Fibonacci(3) = 1 Fibonacci(4) = 2 Fibonacci(5) = 3 Fibonacci(6) = 5 Fibonacci(7) = 8 Fibonacci(8) = 13 Fibonacci(9) = 21 Fibonacci(10) = 34 Fibonacci(11) = 55 Fibonacci(12) = 89 Fibonacci(13) = 144 Fibonacci(14) = 233 Fibonacci(15) = 377 Fibonacci(16) = 610 Fibonacci(17) = 987 Fibonacci(18) = 1597 Fibonacci(19) = 2584 Fibonacci(20) = 4181 Fibonacci(21) = 6765 Fibonacci(22) = 10946 Fibonacci(23) = 17711 Fibonacci(24) = 28657 Fibonacci(25) = 46368 Fibonacci(26) = 75025 Fibonacci(27) = 121393 Fibonacci(28) = 196418 Fibonacci(29) = 317811 Fibonacci(30) = 514229 Fibonacci(31) = 832040 Fibonacci(32) = 1346269 Fibonacci(33) = 2178309 Fibonacci(34) = 3524578 Fibonacci(35) = 5702887 Fibonacci(36) = 9227465 Fibonacci(37) = 14930352 Fibonacci(38) = 24157817 Fibonacci(39) = 39088169 Fibonacci(40) = 63245986 Fibonacci(41) = 102334155 Fibonacci(42) = 165580141 Fibonacci(43) = 267914296 Fibonacci(44) = 433494437 Fibonacci(45) = 701408733 Fibonacci(46) = 1134903170 Fibonacci(47) = 1836311903 Fibonacci(48) = 2971215073 Fibonacci(49) = 4807526976 Fibonacci(50) = 7778742049 Edited by dani.user, 26 October 2016 - 11:18. |
Anunturi
▶ 0 user(s) are reading this topic
0 members, 0 guests, 0 anonymous users