IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Copie d'une partie d'un tableau sur un intervalle régulier


Sujet :

C++

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    91
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 91
    Points : 50
    Points
    50
    Par défaut Copie d'une partie d'un tableau sur un intervalle régulier
    Bonjour,
    J'ai un tableau dont je souhaiterai copier une partie sur des pas régulier :

    unsigned char* tab = new char[N];
    je voudrais donc copier seulement certaines cases de ce tableau, toutes les 5 cases par exemple, soit les indices 0, 5, 10, 15, etc. .

    Existe-t-il une méthode rapide (stl ?) pour effectuer ceci

    NB : l'utilisation d'un unsigned char* est le plus approprié dans mon cas (donc pas de réponse du style : utilise un std::vector, c'est mieux )

    Merci d'avance

  2. #2
    Membre émérite

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Points : 2 252
    Points
    2 252
    Par défaut
    Bonjour,
    Citation Envoyé par olivier21c Voir le message
    je voudrais donc copier seulement certaines cases de ce tableau, toutes les 5 cases par exemple, soit les indices 0, 5, 10, 15, etc. .

    Existe-t-il une méthode rapide (stl ?) pour effectuer ceci
    Une boucle for ?
    A vrai dire ça doit être aussi possible avec un std::copy_if + un prédicat mais c'est beaucoup d'effort pour pas grand chose (copy_if n'est pas présent dans le stl du C++03, il faut se le coder)

    Citation Envoyé par olivier21c Voir le message
    NB : l'utilisation d'un unsigned char* est le plus approprié dans mon cas
    Douteux.

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    91
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 91
    Points : 50
    Points
    50
    Par défaut
    Citation Envoyé par Arzar Voir le message
    Bonjour,

    Une boucle for ?
    A vrai dire ça doit être aussi possible avec un std::copy_if + un prédicat mais c'est beaucoup d'effort pour pas grand chose (copy_if n'est pas présent dans le stl du C++03, il faut se le coder)
    ba la boucle c'est ce que j'utilise, mais je me demandais juste si une solution plus rapide n'existait pas...

    Citation Envoyé par Arzar Voir le message
    Douteux.
    Et bien si dans mon cas c'est la meilleur solution (je précise que je ne l'utilise pas opur des chaîne de caractères ^^)

  4. #4
    Modérateur
    Avatar de bruno_pages
    Homme Profil pro
    ingénieur informaticien à la retraite
    Inscrit en
    Juin 2005
    Messages
    3 534
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : ingénieur informaticien à la retraite
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juin 2005
    Messages : 3 534
    Points : 6 723
    Points
    6 723
    Par défaut
    Citation Envoyé par olivier21c Voir le message
    Citation Envoyé par Arzar
    Douteux.
    je précise que je ne l'utilise pas opur des chaîne de caractères ^^
    alors c'est encore plus douteux

  5. #5
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Salut,
    Plutôt que de travailler sur un prédicat et std::copy_if, à priori, je serais plutôt intervenu sur l'itérateur. Quelque chose comme un itérateur construit à partir d'un autre itérateur et d'un pas et qui ferait un std::advance lors de l'appel de l'opérateur ++. Ensuite, juste un std::copy avec cet itérateur.

    Citation Envoyé par bruno_pages Voir le message
    Citation Envoyé par olivier21c Voir le message
    Citation Envoyé par Arzar
    Douteux.
    je précise que je ne l'utilise pas opur des chaîne de caractères ^^
    alors c'est encore plus douteux
    Pourquoi a-t-on des doutes ? std::vector<unsigned char> c'est un new unsigned char[] .... avec le RAII en bonus. C'est pour ça qu'on a du mal à comprendre que l'allocation dynamique explicite soit le plus approprié. Si c'est le cas, alors, le std::vector aussi...

  6. #6
    Modérateur
    Avatar de bruno_pages
    Homme Profil pro
    ingénieur informaticien à la retraite
    Inscrit en
    Juin 2005
    Messages
    3 534
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : ingénieur informaticien à la retraite
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juin 2005
    Messages : 3 534
    Points : 6 723
    Points
    6 723
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    Pourquoi a-t-on des doutes ?
    à cause de la phrase je ne l'utilise pas opur des chaîne de caractères qui semble laissé penser qu'un vecteur de X (autre que des caractères) est casté en unsigned char * afin de réaliser la copie, mais je suis peu être parano ?

  7. #7
    Membre chevronné
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Points : 2 107
    Points
    2 107
    Par défaut
    Citation Envoyé par bruno_pages Voir le message
    à cause de la phrase je ne l'utilise pas opur des chaîne de caractères qui semble laissé penser qu'un vecteur de X (autre que des caractères) est casté en unsigned char * afin de réaliser la copie, mais je suis peu être parano ?
    Attention, 3DArchi allait pleinement dans ton sens. Il a rappelé que std::vector est mieux, parce que c'est un new T[] qui est réalisé à l'intérieur, avec le RAII en plus !
    Je me rajoute donc à la liste des sceptiques:
    • std::vector : si la taille est susceptible de changer (push_back)
    • boost::array : si la taille est connu à la compilation.


    Au posteur :
    Tu cherches quelque chose de compliqué à base de STL pour faire le travail de copie d'un intervalle? Utilise une boucle for, c'est pas grave, et tu vas moins te prendre la tête.
    Par contre, tu nous sors un beau unsigned char*, alors que la STL fourni son équivalent en mieux ! Là par contre tu risques la prise de tête.
    Rigolo, hein?

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    91
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 91
    Points : 50
    Points
    50
    Par défaut
    Bonjour à tous,

    Je suis pleinement conscient que le std::vector fournit des avantages à l'utilisation d'un unsigned char*. Mais ici les intérêts que présente l'utilisation d'un vector ne m'intéresse pas (j'avais pourtant bien précisé dans mon premier post de l'inutilité d'un discussion autour de l'utilisation alternative de vector, mais bon faut croire que les gens aiment dévier les discussions dans un sens ou dans l'autre...). Les vector ne sont pas forcément la seule solution à tout codage.

    La seule question à débattre ici est la rapidité améliorable en itérant d'une autre manière pour avoir accès à mes données. Si effectivemetn l'utilisation d'un vector me le permettait, pourquoi pas discutier de son utilisation, sinon c'est hors sujet à propos de mon post.
    Quand je parlais de l'utilisation de STL pour itérer, ce n'était qu'une suggestion, j'étais ouvert à toute autre proposition.

  9. #9
    Membre expert
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    1 415
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2007
    Messages : 1 415
    Points : 3 159
    Points
    3 159
    Par défaut
    Salut Olivier

    Au vu des discussions, on peut supposer que tu sais utiliser correctement des pointeurs, ou du moins que tu sais ce que tu risques à le croire

    Il n'y a rien de plus rapide qu'une boucle for. De toute façon, une fonction qui le fait à ta place aurait sans aucun doute utilisé une boucle for. Le seul truc à éventuellement optimiser, et à mon avis tu n'y gagnerai pas énormément, c'est jouer avec l'arithmétique des pointeurs. Mais c'est vraiment du chipotage, ne perd pas trop de temps sur la question .

  10. #10
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    91
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 91
    Points : 50
    Points
    50
    Par défaut
    Merci de la réponse.
    En effet je cherchai juste à savoir si il existait une méthode existante (ou à implémenter) qui serait plus rapide. Apparemment non dans mon cas.

    Je n'ai bien sur rien contre l'utilisation des vectors, et plus généralement de tous les conteneurs de la STL, seulement ici d'une part je pars d'un code existant conséquent où l'utilisation des pointeurs était tout à fait approprié. Le point le plus important est sur cette partie est le temps d'éxécutions, il y a beaucoup d'allers-retour et l'utilisation d'un vector n'aurait que peu d'avantage, si ce n'est une facilité d'utilisation dont je n'ai pas le besoin.
    J'avais moi même fait il y a quelque temps des modification sur une partie des pointeurs en unsigned char* par des vector, et j'y perdais en vitesse (de peu, mais chaque ms est importante ici).

    Si personne n'a d'autres idées, on peut considérer le sujet clos pour le moment

  11. #11
    Membre chevronné
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Points : 2 107
    Points
    2 107
    Par défaut
    Citation Envoyé par jblecanard Voir le message
    Au vu des discussions, on peut supposer que tu sais utiliser correctement des pointeurs, ou du moins que tu sais ce que tu risques à le croire
    Une fois que tu as lu des bouquins du genre "Exceptionnal C++", on se rend vite compte que les exceptions sont partout, et qu'il est extrêmement difficile d'écrire du code code exception-safe, c'est à dire un code qui se comporte correctement en cas d'exceptions, et tout celà sans fuite mémoire.
    Tous les conteneurs standards sont exception-safe, au prix de sacré gouttes de sueurs par beaucoup de programmeurs. Les epsilons perdus en performance sont compensés par la sécurité qu'ils apportent.

    @olivier21c : la boucle for fonctionnera très bien. Sujet clos alors.

  12. #12
    Membre expert
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    1 415
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2007
    Messages : 1 415
    Points : 3 159
    Points
    3 159
    Par défaut
    Citation Envoyé par poukill Voir le message
    Une fois que tu as lu des bouquins du genre "Exceptionnal C++", on se rend vite compte que les exceptions sont partout, et qu'il est extrêmement difficile d'écrire du code code exception-safe, c'est à dire un code qui se comporte correctement en cas d'exceptions, et tout celà sans fuite mémoire.
    Tous les conteneurs standards sont exception-safe, au prix de sacré gouttes de sueurs par beaucoup de programmeurs. Les epsilons perdus en performance sont compensés par la sécurité qu'ils apportent.
    Hé oui, d'où ma petite remarque. A moins que tu ne veuilles mettre les mains dans l'assembleur, le sujet est sûrement clos .

  13. #13
    Membre émérite

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Points : 2 252
    Points
    2 252
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    Salut,
    Plutôt que de travailler sur un prédicat et std::copy_if, à priori, je serais plutôt intervenu sur l'itérateur. Quelque chose comme un itérateur construit à partir d'un autre itérateur et d'un pas et qui ferait un std::advance lors de l'appel de l'opérateur ++. Ensuite, juste un std::copy avec cet itérateur.
    C'est exactement l'approche retenu par boost.RangeEx, qui est actuellement dans le trunk (sous le nom boost.Range) et sera dispo dans la version 1.43 !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
     
    #include <boost/range/algorithm/copy.hpp>
    #include <boost/range/adaptor/strided.hpp>
     
    using boost::copy;
    using boost::begin;
    using boost::adaptors::stride;
     
    int main()
    {
       int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
       int arr2[5];
       int arr3[5];
       int step = 2;
     
       // 1. boucle for
       for(int i = 0, j =0 ; i < 10 ; i += step, j++)
       {
          arr2[j] = arr[i];
       }
     
       // 2. boost.RangeEx
       copy(stride(arr, step), arr3); 
    }
    L'assembleur généré m'a l'air un poil moins bon, mais ce one-liner "copy(stride(arr, step, arr3)" est quand même superbe, non ?

  14. #14
    Membre chevronné
    Avatar de Joel F
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Septembre 2002
    Messages
    918
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2002
    Messages : 918
    Points : 1 921
    Points
    1 921
    Par défaut
    Citation Envoyé par Arzar Voir le message
    L'assembleur généré m'a l'air un poil moins bon
    Dans ce genre de cas, on s'en tape. le point limitant, c''est la BP mémoire. Alors avoir 3-4 instructions en plus ... bouarf.

  15. #15
    Membre expert
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    1 415
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2007
    Messages : 1 415
    Points : 3 159
    Points
    3 159
    Par défaut
    Citation Envoyé par Arzar Voir le message
    mais ce one-liner "copy(stride(arr, step, arr3)" est quand même superbe, non ?
    Oui oui boost envoie du pâté comme d'hab

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 7
    Dernier message: 11/05/2014, 08h12
  2. Calcul sur une partie d'un tableau défini sous VBA
    Par VBA_LOVER dans le forum Macros et VBA Excel
    Réponses: 6
    Dernier message: 20/08/2009, 12h27
  3. Scrollbar sur une partie d'un tableau
    Par Dams59 dans le forum Balisage (X)HTML et validation W3C
    Réponses: 3
    Dernier message: 24/04/2007, 09h40
  4. [Tableau] récupérer une partie d'un tableau
    Par keyra dans le forum Collection et Stream
    Réponses: 2
    Dernier message: 07/02/2006, 22h17
  5. passer une partie d'un tableau en paramettre.
    Par monstroplante dans le forum Langage
    Réponses: 13
    Dernier message: 04/11/2005, 01h22

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo