Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/154.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C+;中是否有与Python range()等价的紧凑型+/STL_C++_Python - Fatal编程技术网

C++ C+;中是否有与Python range()等价的紧凑型+/STL

C++ C+;中是否有与Python range()等价的紧凑型+/STL,c++,python,C++,Python,如何使用C++/STL实现以下等效功能?我想用一系列值[min,max]填充std::vector 我想我可以使用std::generate\u n并提供一个函子来生成序列,但我想知道是否有更简洁的方法使用STL来实现这一点?在C++11中,有std::iota: #include <vector> #include <numeric> //std::iota std::vector<int> x(10); std::iota(std::begin(x),

如何使用C++/STL实现以下等效功能?我想用一系列值[min,max]填充
std::vector


我想我可以使用
std::generate\u n
并提供一个函子来生成序列,但我想知道是否有更简洁的方法使用STL来实现这一点?

在C++11中,有
std::iota

#include <vector>
#include <numeric> //std::iota

std::vector<int> x(10);
std::iota(std::begin(x), std::end(x), 0); //0 is the starting number
#包括
#包括//标准::物联网
std::向量x(10);
std::iota(std::begin(x),std::end(x),0);//0是起始编号

我不知道有什么方法可以像在python中那样进行,但另一种方法显然是for循环:

for (int i = range1; i < range2; ++i) {
    x.push_back(i);
}
for(int i=range1;i
chris的答案更好,但如果您有c++11,则有:

std::向量x;
boost::push_back(x,boost::irange(0,10));

boost::irange
,但它不提供浮点、负步骤,并且不能直接初始化stl容器

还有
数值范围

在RO中,要初始化向量:

vector<int> V=range(10);

对于不能使用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
向量x(10,0);//0是起始数,10是范围大小 transform(x.begin(),x.end(),++x.begin(),bind2nd(plus(),1));//1是增量
如果不能使用C++11,可以使用
std::partial_sum
生成从1到10的数字。如果需要从0到9的数字,可以使用transform减去1:

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));
std::vector my_数据(10,1);
std::部分和(my_data.begin()、my_data.end()、my_data.begin());
std::transform(my_data.begin()、my_data.end()、my_data.begin()、bind2nd(std::减号()、1));

我最后编写了一些实用函数来实现这一点。您可以按如下方式使用它们:

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));
}
#包括
#包括
模板
std::矢量范围(IntType start、IntType stop、IntType step)
{
如果(步骤==IntType(0))
{
throw std::无效的_参数(“范围的步长必须非零”);
}
std::向量结果;
IntType i=启动;
而((步骤>0)?(i<停止):(i>停止))
{
结果:推回(i);
i+=阶跃;
}
返回结果;
}
模板
std::矢量范围(IntType start、IntType stop)
{
返回范围(开始、停止、输入类型(1));
}
模板
标准::矢量范围(IntType stop)
{
返回范围(IntType(0)、stop、IntType(1));
}

多年来,我一直在使用这个库来实现这个确切的目的:

工作非常好,代理已优化

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';
for(自动i:范围(1,5))
cout下面类似的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
#包括
#包括
#包括
#包括
使用名称空间std;
//定义范围函数(仅一次)
模板
矢量范围(T N1,T N2){
向量数(N2-N1);
物联网(number.begin()、number.end()、N1);
返回号码;
}
矢量arr=范围(0,10);
矢量arr2=范围(5,8);

对于(auto n:arr){cout我不久前编写了以下_range类,其行为类似于Python range(将其置于“range.h”):

#pragma一次
#包括
#包括
模板
类范围
{
康斯特克夫罗姆,肯德,克斯特普;
公众:
///////////////////////////////////////////////////////////
//建造师
///////////////////////////////////////////////////////////
//
//输入:
//from—序列的起始编号。
//结束-生成最多到的数字,但不包括此数字。
//步骤-序列中每个数字之间的差值。
//
//备注:
//参数必须全部为正或全部为负
//
_范围(常数T从,常数T结束,常数T步=1)
:kFrom(from)、kEnd(end)、kStep(step)
{
断言(kStep!=0);
断言((kFrom>=0&&kEnd>0&&kStep>0)| |(kFrom<0&&kEnd<0&&kStep<0));
}
//默认值from==0,step==1
_范围(常数T端)
:kFrom(0)、kEnd(end)、kStep(1)
{
断言(kEnd>0);
}
公众:
等级(范围)iter
{
T-fVal;
const T kStep;
公众:
_距离(常数tv,常数T步):fVal(v),kStep(步){}
运算符T()常量{return fVal;}
运算符常量T&({return fVal;}
常量T运算符*()常量{return fVal;}
const _range_iter&operator++(){fVal+=kStep;返回*this;}
布尔运算符==(常数_范围_iter&ri)常数
{
返回!运算符!=(ri);
}
布尔运算符!=(常数_范围_iter&ri)常数
{   
//这是一个棘手的部分-在使用迭代器时
//它只检查一次!=必须点击才能停止;
//但是,如果将kStart增加N倍kSteps跳过kEnd,则这不起作用
返回fVal<0?fVal>ri.fVal:fVal
运算符std::vector(无效)
{
std::向量重排列;
对于(ti=kFrom;i
typedef_范围;
一些测试代码如下所示:

#include "range.h" 
#include <iterator>
#include <fstream>

using namespace std;

void RangeTest( void )
{
    ofstream ostr( "RangeTest.txt" );
    if( ostr.is_open() == false )
        return;

    // 1:
    ostr << "1st test:" << endl;

    vector< float > v = _range< float >( 256 );
    copy( v.begin(), v.end(), ostream_iterator< float >( ostr, ", " ) );

    // 2:
    ostr << endl << "2nd test:" << endl;

    vector< size_t >    v_size_t( range( 0, 100, 13 ) );
    for( auto a : v_size_t )
        ostr << a << ", ";

    // 3:
    ostr << endl << "3rd test:" << endl;

    auto vvv = range( 123 );    // 0..122 inclusive, with step 1
    for( auto a : vvv )
        ostr << a << ", ";

    // 4:
    ostr << endl << "4th test:" << endl;

    // Can be used in the nested loops as well
    for( auto i : _range< float >( 0, 256, 16.5 ) ) 
    {
        for( auto j : _range< int >( -2, -16, -3 ) ) 
        {
            ostr << j << ", ";
        }
        ostr << endl << i << endl;
    }

}
#包括“range.h”
#包括
#包括
使用名称空间std;
无效范围测试(无效)
{
流介电常数
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';
#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
#pragma once
#include <vector>
#include <cassert>

template < typename T = size_t >
class _range 
{
        const T kFrom, kEnd, kStep;

    public:

        ///////////////////////////////////////////////////////////
        // Constructor 
        ///////////////////////////////////////////////////////////
        //
        // INPUT:
        //      from - Starting number of the sequence.
        //      end - Generate numbers up to, but not including this number.
        //      step -  Difference between each number in the sequence.     
        //
        // REMARKS:
        //      Parameters must be all positive or all negative
        //
        _range( const T from, const T end, const T step = 1 ) 
            : kFrom( from ), kEnd( end ), kStep( step ) 
        {
            assert( kStep != 0 );
            assert( ( kFrom >= 0 && kEnd > 0 && kStep > 0 ) || ( kFrom < 0 && kEnd < 0 && kStep < 0 ) );
        }

        // Default from==0, step==1
        _range( const T end ) 
            : kFrom( 0 ), kEnd( end ), kStep( 1 ) 
        {
            assert( kEnd > 0 );
        }

    public:

        class _range_iter 
        {
            T fVal;
            const T kStep;
        public:
            _range_iter( const T v, const T step ) : fVal( v ), kStep( step ) {}
            operator T  () const            { return fVal; }
            operator const T & ()           { return fVal; }
            const T operator * () const     { return fVal; }
            const _range_iter & operator ++ ()  { fVal += kStep; return * this; }


            bool operator == ( const _range_iter & ri ) const
            {
                return ! operator != ( ri );
            }

            bool operator != ( const _range_iter & ri ) const
            {   
                // This is a tricky part - when working with iterators
                // it checks only once for != which must be a hit to stop;
                // However, this does not work if increasing kStart by N times kSteps skips over kEnd
                return fVal < 0 ? fVal > ri.fVal : fVal < ri.fVal;  
            }                                               
        };                                                  

        const _range_iter begin()   { return _range_iter( kFrom, kStep ); }
        const _range_iter end()     { return _range_iter( kEnd, kStep ); }

    public:

        // Conversion to any vector< T >
        operator std::vector< T > ( void ) 
        {
            std::vector< T > retRange;
            for( T i = kFrom; i < kEnd; i += kStep )
                retRange.push_back( i );
            return retRange;    // use move semantics here
        }
};


// A helper to use pure range meaning _range< size_t >
typedef _range<>    range;
#include "range.h" 
#include <iterator>
#include <fstream>

using namespace std;

void RangeTest( void )
{
    ofstream ostr( "RangeTest.txt" );
    if( ostr.is_open() == false )
        return;

    // 1:
    ostr << "1st test:" << endl;

    vector< float > v = _range< float >( 256 );
    copy( v.begin(), v.end(), ostream_iterator< float >( ostr, ", " ) );

    // 2:
    ostr << endl << "2nd test:" << endl;

    vector< size_t >    v_size_t( range( 0, 100, 13 ) );
    for( auto a : v_size_t )
        ostr << a << ", ";

    // 3:
    ostr << endl << "3rd test:" << endl;

    auto vvv = range( 123 );    // 0..122 inclusive, with step 1
    for( auto a : vvv )
        ostr << a << ", ";

    // 4:
    ostr << endl << "4th test:" << endl;

    // Can be used in the nested loops as well
    for( auto i : _range< float >( 0, 256, 16.5 ) ) 
    {
        for( auto j : _range< int >( -2, -16, -3 ) ) 
        {
            ostr << j << ", ";
        }
        ostr << endl << i << endl;
    }

}