快速创建一个由连续值组成的向量

5
如何快速地从连续值创建向量

Eg.:

vector<int> vec (4, 100);
for (vector<int>::iterator it = vec.begin(); it != vec.end(); ++it) {
    cout << *it << endl;
}

输出:

# 100
# 100
# 100
# 100

我想要
vector<int> vec (100, "0 to N");

我希望了解实现此目标的最有效方式,例如,不使用循环。
N 是一个运行时变量。

你明白你会在某个地方使用循环,对吧? - GManNickG
是的,但我会保留整洁的代码! - Alan Valejo
3
循环并不一定会使代码变得混乱...而少量的代码行并不能否认易读性。但毕竟这是一个有趣的问题 :-) - Natan Streppel
6个回答

23

这里有另一种方法...

int start = 27;
std::vector<int> v(100);
std::iota(v.begin(), v.end(), start);

16

下面是一个不使用可见循环,只使用标准C++库的版本。它很好地展示了将lambda用作生成器的用法。使用reserve()是可选的,只是为了避免多次内存分配。

std::vector<int> v;
v.reserve(100);
int n(0);
std::generate_n(std::back_inserter(v), 100, [n]()mutable { return n++; });

@HappyYellowFace:我不知道哪个更好,但我可以想象复制整数范围可以一次处理多个整数,但它也会触及更多的内存。上面的代码可能可以展开,并且编译器可能会查看lambda表达式。需要进行测量才能确定,我可以想象这也取决于std::generate_n()的实现方式:标准库可以查看std::back_inserter(),甚至自动执行reserve() - Dietmar Kühl
2
这可以简化为 std::generate_n(std::back_inserter(v), 100, [&](){ return v.size(); }); - Tiago Peixoto

2
您想要的是像这样的东西:
std::vector<unsigned int> second(
    boost::counting_iterator<unsigned int>(0U),
    boost::counting_iterator<unsigned int>(99U));

1
@Cornstalks:迭代器是随机访问迭代器(在这种情况下),因此只会发生一次分配。 - GManNickG
@GManNickG:std::vector的构造函数接受一个InputIterator,而不是RandomAccessIterator。除非实现有一个RandomAccessIterator的特殊情况,否则它将不得不重复增长,因为InputIterator没有办法给出两个迭代器的范围。 - Cornstalks
@Cornstalks:这正是我所说的。任何基本的std::vector实现(以及所有真正的实现)都会为随机访问迭代器进行特化。构造函数只指定了最弱的可允许迭代器,它可以对实际迭代器进行任何操作。 - GManNickG
@Cornstalks:任何自尊的std::vector<T>实现,如果传递给构造函数的是随机访问迭代器,都会确定序列的大小!只需要进行少量模板特化处理即可专门处理模板参数为随机访问迭代器的情况。 - Dietmar Kühl

1
使用生成算法:

#include <iostream>     // std::cout
#include <algorithm>    // std::generate
#include <vector>       // std::vector
#include <iterator>

// function generator:
struct one_more { 
  int _count;
  one_more() : _count(0) {}
  int operator()() {
      return _count++;
  }
};

int main () {
  std::vector<int> myvector (100);
  std::generate (myvector.begin(), myvector.end(), one_more());

  std::copy(myvector.begin(), myvector.end(), std::ostream_iterator<int>(std::cout, " "));
  return 0;
}

0

我知道这是一个老问题,但我目前正在尝试使用library来处理这个问题。它需要c++14。

#include "htl.hpp"

htl::Token _;

std::vector<int> vec = _[0, _, 100];
// or
for (auto const e: _[0, _, 100]) { ... }

0
const int num_seconds = 100;
vector<int> second( num_seconds );
for( int n = 0 ; n < num_seconds ; ++n ) {
    second[ n ] = n;
}

我不想使用循环。还有其他方法吗? - Alan Valejo
1
@AlanValejo:每个答案都会有一个循环,无论是可见的还是不可见的。 - GManNickG

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接