120 votes

utiliser std::fill pour remplir le vecteur avec des nombres croissants

Je voudrais remplir un vector<int> en utilisant std::fill mais au lieu d'une valeur, le vecteur doit contenir des nombres en ordre croissant après.

J'ai essayé d'y parvenir en itérant le troisième paramètre de la fonction par un, mais cela ne me donnait que des vecteurs remplis de 1 ou de 2 (en fonction de la position de l'argument de la fonction). ++ opérateur).

Ejemplo:

vector<int> ivec;
int i = 0;
std::fill(ivec.begin(), ivec.end(), i++); // elements are set to 1
std::fill(ivec.begin(), ivec.end(), ++i); // elements are set to 2

2voto

no one special Points 343

En termes de performances, il est préférable d'initialiser le vecteur à l'aide de la fonction reserve() combiné avec push_back() comme dans l'exemple ci-dessous :

const int numberOfElements = 10;

std::vector<int> data;
data.reserve(numberOfElements);

for(int i = 0; i < numberOfElements; i++)
    data.push_back(i);

Tous les std::fill , std::generate etc. fonctionnent sur une plage de contenu vectoriel existant et, par conséquent, le vecteur doit être rempli avec des données plus tôt. Même en faisant ce qui suit : std::vector<int> data(10); crée un vecteur dont tous les éléments sont fixés à leur valeur par défaut (c'est-à-dire 0 en cas de int ).

Le code ci-dessus évite d'initialiser le contenu du vecteur avant de le remplir avec les données que vous voulez vraiment. Les performances de cette solution sont bien visibles sur les grands ensembles de données.

1voto

King Kokonut Points 19

Si vous vraiment veulent utiliser std::fill et sont confinés à C++98, vous pouvez utiliser quelque chose comme ce qui suit,

#include <algorithm>
#include <iterator>
#include <iostream>
#include <vector>

struct increasing {
    increasing(int start) : x(start) {}
    operator int () const { return x++; }
    mutable int x;
};

int main(int argc, char* argv[])
{
    using namespace std;

    vector<int> v(10);
    fill(v.begin(), v.end(), increasing(0));
    copy(v.begin(), v.end(), ostream_iterator<int>(cout, " "));
    cout << endl;
    return 0;
}

1voto

Dawid Points 585

Je sais que c'est une vieille question, mais je joue actuellement avec bibliothèque pour gérer exactement ce problème. Il nécessite c++14.

#include "htl.hpp"

htl::Token _;

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

// supports also custom steps
// _[0, _%3, 100] == 0, 4, 7, 10, ...

1voto

amirt01 Points 3

Le meilleur moyen que j'ai trouvé est d'utiliser std::generate_n con std::back_insert_iterator . Cet exemple est en fait donné dans le Page de cppreference pour std::back_insert_iterator . Une modification que j'apporterais à cet exemple, cependant, serait de réserver le nombre d'insertions que vous êtes sur le point de faire pour minimiser les réallocations comme ceci :

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

0voto

Adam Erickson Points 44

J'ai créé une simple fonction modèle, Sequence() pour générer des séquences de nombres. La fonctionnalité suit le seq() dans R ( lien ). L'avantage de cette fonction est qu'elle permet de générer une grande variété de séquences et de types de nombres.

#include <iostream>
#include <vector>

template <typename T>
std::vector<T> Sequence(T min, T max, T by) {
  size_t n_elements = ((max - min) / by) + 1;
  std::vector<T> vec(n_elements);
  min -= by;
  for (size_t i = 0; i < vec.size(); ++i) {
    min += by;
    vec[i] = min;
  }
  return vec;
}

Exemple d'utilisation :

int main()
{
    auto vec = Sequence(0., 10., 0.5);
    for(auto &v : vec) {
        std::cout << v << std::endl;
    }
}

La seule réserve est que tous les nombres doivent être du même type inféré. En d'autres termes, pour les doubles ou les flottants, incluez les décimales pour toutes les entrées, comme indiqué.

Mise à jour : 14 juin 2018

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X