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

173voto

BoBTFish Points 6610

Utilisez de préférence std::iota comme ça :

std::vector<int> v(100) ; // vector with 100 ints.
std::iota (std::begin(v), std::end(v), 0); // Fill with 0, 1, ..., 99.

Cela dit, si vous n'avez pas de c++11 support (encore un vrai problème là où je travaille), utiliser std::generate comme ça :

struct IncGenerator {
    int current_;
    IncGenerator (int start) : current_(start) {}
    int operator() () { return current_++; }
};

// ...

std::vector<int> v(100) ; // vector with 100 ints.
IncGenerator g (0);
std::generate( v.begin(), v.end(), g); // Fill with the result of calling g() repeatedly.

60voto

Vous devez utiliser std::iota (défini dans <numeric> ):

  std::vector<int> ivec(100);
  std::iota(ivec.begin(), ivec.end(), 0); // ivec will become: [0..99]

Parce que std::fill affecte simplement la valeur fixe donnée aux éléments de la plage donnée. [n1,n2) . Y std::iota remplit l'intervalle donné [n1, n2) avec des valeurs augmentant séquentiellement, en commençant par la valeur initiale et en utilisant ensuite ++value Vous pouvez également utiliser std::generate comme alternative.

N'oubliez pas que std::iota est un algorithme C++11 STL. Mais beaucoup de compilateurs modernes le supportent, par exemple GCC, Clang et VS2012 : http://msdn.microsoft.com/en-us/library/vstudio/jj651033.aspx

P.S. Cette fonction est nommée d'après la fonction entière du langage de programmation APL, et signifie une lettre grecque iota. Je suppose qu'à l'origine, ce nom étrange a été choisi en APL parce qu'il ressemble à une lettre grecque iota. “integer” (même si, en mathématiques, iota est largement utilisé pour désigner la partie imaginaire d'un nombre complexe).

15voto

James Kanze Points 96599

Mon premier choix (même en C++11) serait le suivant boost::counting_iterator :

std::vector<int> ivec( boost::counting_iterator<int>( 0 ),
                       boost::counting_iterator<int>( n ) );

ou si le vecteur a déjà été construit :

std::copy( boost::counting_iterator<int>( 0 ),
           boost::counting_iterator<int>( ivec.size() ),
           ivec.begin() );

Si vous ne pouvez pas utiliser Boost : soit std::generate (comme suggéré dans d'autres réponses), ou mettre en œuvre counting_iterator vous-même, si vous en avez besoin à différents endroits. (Avec Boost, vous pouvez utiliser a transform_iterator d'un counting_iterator pour créer tous les de séquences intéressantes. Sans Boost, vous pouvez faire beaucoup beaucoup de choses à la main, soit sous la forme d'un type d'objet générateur pour std::generate ou comme quelque chose que l'on peut brancher sur une main. itérateur de comptage écrit à la main).

11voto

brainsandwich Points 432

J'ai vu les réponses avec std::generate mais vous pouvez aussi "améliorer" cela en utilisant des variables statiques à l'intérieur de la lambda, au lieu de déclarer un compteur en dehors de la fonction ou de créer une classe de générateur :

std::vector<int> vec(10);
std::generate(vec.begin(), vec.end(), [] {
    static int i = 0;
    return i++;
});

Je le trouve un peu plus concis

7voto

rashedcs Points 976

Nous pouvons utiliser générer qui existe dans le fichier d'en-tête de l'algorithme.

Extrait de code :

#include<bits/stdc++.h>
using namespace std;

int main()
{
    ios::sync_with_stdio(false);

    vector<int>v(10);

    int n=0;

    generate(v.begin(), v.end(), [&n] { return n++;});

    for(auto item : v)
    {
      cout<<item<<" ";
    }
    cout<<endl;

    return 0;
}

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