Генератор!!!

Матеріал з wiki
Перейти до: навігація, пошук
Onpage keywords chain search with * wildcard. Example: sear* my nam* will find Searh my names and search my Name


Генератор — в інформатиці, це підпрограма, що контролює ітерації в циклі.

Генератор є підвидом ітератора.

Різниця між ітератором і генератором:

Ітератор проходить по колекції по одному елементу за раз. Генератор генерує елементи послідовності по одному елементу за раз. Генератор може бути реалізований у вигляді наступних конструкцій потоку керування як:

співпрограма; продовження першого порядку. Генератор є частковим випадком співпрограми, оскільки завжди повертає керування до того коду, який його викликав.


Приклади в різних мовах програмування

C#

public static IEnumerable<int> GetEven(IEnumerable<int> numbers) {

   foreach (int i in numbers)
       if ((i % 2) == 0)
           yield return i;

}

F#

seq {

   for b in 0 .. 25 do
       if b < 15 then
           yield b * b

}

C++

C++11 дозволяє застосовувати foreach цикли до будь-якого класу, що надає функції begin та end. Отже, можливо написати подібний до генератора клас визначивши обидва ці методи і методи ітератора (operator!=, operator++ і operator*) в одному класі. Наприклад, можливо написати таку програму:

  1. include <iostream>

int main() {

   for (int i: range(10))
   {
       std::cout << i << std::endl;
   }
   return 0;

} Просте втілення класа range виглядало б так:

class range { private:

   int last;
   int iter;

public:

   range(int end):
       last(end),
       iter(0)
   {}
   // Повертають ітератор
   const range& begin() const { return *this; }
   const range& end() const { return *this; }
   // Функції ітератора
   bool operator!=(const range&) const { return iter < last; }
   void operator++() { ++iter; }
   int operator*() const { return iter; }

}; В Microsoft Visual C++ 2015 реалізовані деякі пропозиції для C++17

  1. include <experimental/generator>

using namespace std::experimental;

inline generator<int> values() { for (int i = 0; i < 100; ++i) { __yield_value i*i; } } Можливо писати в стилі, який через вкладеність викликів, читатиметься знизу вверх:

auto seq = take(5 ,transform([](int x) {return x*x;} ,where([](int x) {return x % 2 == 0;} ,fibonacci() )));

for (auto i : seq) printf("%d ", i);

Посилання

yield (C# Reference) Some Details on F# Computation Expressions Resumable Functions (revision 4) Resumable functions in C++ More about resumable functions in C++

Developed by Інститут Програмних Систем