Существует ли компактный эквивалент Python range () в C ++ / STL

Как я могу сделать эквивалент следующего использования C ++ / STL? Я хочу заполнить std::vector с диапазоном значений [min, max).

 # Python >>> x = range(0, 10) >>> x [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 

Я полагаю, что я мог бы использовать std::generate_n и предоставить функтору для генерации последовательности, но мне было интересно, есть ли более короткий способ сделать это с помощью STL?

9 Solutions collect form web for “Существует ли компактный эквивалент Python range () в C ++ / STL”

В C ++ 11 есть std::iota :

 std::vector<int> x(10); std::iota(std::begin(x), std::end(x), 0); //0 is the starting number 

Существует boost :: irange :

 std::vector<int> x; boost::push_back(x, boost::irange(0, 10)); 

Существует boost::irange , но он не обеспечивает с плавающей точкой, отрицательные шаги и не может напрямую инициализировать stl-контейнеры.

В моей библиотеке RO также есть numeric_range

В RO для инициализации вектора:

 vector<int> V=range(10); 

Пример cut-n-paste из doc-страницы (оценщик scc c ++):

 // [0,N) open-ended range. Only range from 1-arg range() is open-ended. scc 'range(5)' {0, 1, 2, 3, 4} // [0,N] closed range scc 'range(1,5)' {1, 2, 3, 4, 5} // floating point scc 'range(1,5,0.5)' {1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5} // negative step scc 'range(10,0,-1.5)' {10, 8.5, 7, 5.5, 4, 2.5, 1} // any arithmetic type scc "range('a','z')" abcdefghijklmnopqrstu vwxyz // no need for verbose iota. (vint - vector<int>) scc 'vint V = range(5); V' {0, 1, 2, 3, 4} // is lazy scc 'auto NR = range(1,999999999999999999l); *find(NR.begin(), NR.end(), 5)' 5 // Classic pipe. Alogorithms are from std:: scc 'vint{3,1,2,3} | sort | unique | reverse' {3, 2, 1} // Assign 42 to 2..5 scc 'vint V=range(0,9); range(V/2, V/5) = 42; V' {0, 1, 42, 42, 42, 5, 6, 7, 8, 9} // Find (brute force algorithm) maximum of `cos(x)` in interval: `8 < x < 9`: scc 'range(8, 9, 0.01) * cos || max' -0.1455 // Integrate sin(x) from 0 to pi scc 'auto d=0.001; (range(0,pi,d) * sin || add) * d' 2 // Total length of strings in vector of strings scc 'vstr V{"aaa", "bb", "cccc"}; V * size || add' 9 // Assign to c-string, then append `"XYZ"` and then remove `"bc"` substring : scc 'char s[99]; range(s) = "abc"; (range(s) << "XYZ") - "bc"' aXYZ // Hide phone number: scc "str S=\"John Q Public (650)1234567\"; S|isdigit='X'; S" John Q Public (XXX)XXXXXXX 

В итоге я написал некоторые служебные функции для этого. Вы можете использовать их следующим образом:

 auto x = range(10); // [0, ..., 9] auto y = range(2, 20); // [2, ..., 19] auto z = range(10, 2, -2); // [10, 8, 6, 4] 

Код:

 #include <vector> #include <stdexcept> template <typename IntType> std::vector<IntType> range(IntType start, IntType stop, IntType step) { if (step == IntType(0)) { throw std::invalid_argument("step for range must be non-zero"); } std::vector<IntType> result; IntType i = start; while ((step > 0) ? (i < stop) : (i > stop)) { result.push_back(i); i += step; } return result; } template <typename IntType> std::vector<IntType> range(IntType start, IntType stop) { return range(start, stop, IntType(1)); } template <typename IntType> std::vector<IntType> range(IntType stop) { return range(IntType(0), stop, IntType(1)); } 

Я не знаю, как это сделать, как в python, но для альтернативы, очевидно, для этого:

 for (int i = range1; i < range2; ++i) { x.push_back(i); } 

Ответ криса лучше, хотя если у вас есть c ++ 11

Для тех, кто не может использовать C ++ 11 или библиотеки:

 vector<int> x(10,0); // 0 is the starting number, 10 is the range size transform(x.begin(),x.end(),++x.begin(),bind2nd(plus<int>(),1)); // 1 is the increment 

Если вы не можете использовать C ++ 11, вы можете использовать std::partial_sum для генерации чисел от 1 до 10. И если вам нужны цифры от 0 до 9, вы можете затем вычесть 1 с помощью transform:

 std::vector<int> my_data( 10, 1 ); std::partial_sum( my_data.begin(), my_data.end(), my_data.begin() ); std::transform(my_data.begin(), my_data.end(), my_data.begin(), bind2nd(std::minus<int>(), 1)); 

Я использую эту библиотеку для этой цели в течение многих лет:

https://github.com/klmr/cpp11-range

Работает очень хорошо, и прокси оптимизированы.

 for (auto i : range(1, 5)) cout << i << "\n"; for (auto u : range(0u)) if (u == 3u) break; else cout << u << "\n"; for (auto c : range('a', 'd')) cout << c << "\n"; for (auto i : range(100).step(-3)) if (i < 90) break; else cout << i << "\n"; for (auto i : indices({"foo", "bar"})) cout << i << '\n'; 

Функция range (), аналогичная приведенной ниже, поможет:

 #include <algorithm> #include <iostream> #include <numeric> #include <vector> using namespace std; // define range function (only once) template <typename T> vector <T> range(T N1, T N2) { vector<T> numbers(N2-N1); iota(numbers.begin(), numbers.end(), N1); return numbers; } vector <int> arr = range(0, 10); vector <int> arr2 = range(5, 8); for (auto n : arr) { cout << n << " "; } cout << endl; // output: 0 1 2 3 4 5 6 7 8 9 for (auto n : arr2) { cout << n << " "; } cout << endl; // output: 5 6 7 
  • Передача массива Python в c ++ с помощью SWIG
  • IronPython throw InsufficientMemoryException при использовании numpy в потоках
  • Код Python вызывает библиотеку C, которая создает потоки ОС, которые в конечном итоге вызывают обратные вызовы Python
  • Модуль Python C - Malloc не работает в конкретной версии Python
  • JAXB эквивалент для генерации классов c ++ из xsd?
  • Как использовать malloc и бесплатно с python ctypes?
  • Хороший язык для разработки игрового сервера?
  • Вызывается ли этот PyList_Append (список, Py_BuildValue (...))?
  • Повысить переносимость Python
  • Перенос на numpy api 1.7
  • Компиляция кода C, который использует как R, так и numpy для Linux
  •  
    Interesting Posts for Van-Lav
    Python - лучший язык программирования в мире.