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

SAP Discussion :

[ABAP Recursif] Construction de tableau de combinaisons (pour amateurs de casse-tête)


Sujet :

SAP

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2015
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2015
    Messages : 2
    Points : 1
    Points
    1
    Par défaut [ABAP Recursif] Construction de tableau de combinaisons (pour amateurs de casse-tête)
    Bonjour,

    Voici un petit challenge:

    Dans le cadre d'un projet ABAP, il m'est demandé en partant un tableau de deux colonnes (exemple1) de créer un autre tableau des combinaisons possibles (exemple2).
    La colonne "X" représente le paramètre. La colonne "Y" représente les valeurs du paramètre.
    exemple1:
    X (param)
    Y (valeurs)
    A a1
    A a2
    A a3
    B b1
    B b2
    C c1
    C c2


    Description du tableau attendu (exemple2):
    Tableau identifiant toute les combinaisons possibles (3 colonnes).
    La nouvelle colonne "z" représente le numéro de la combinaison. Il y a autant de ligne par combinaison qu'il y a de paramètres (dans notre cas 3 lignes car A,B et C).
    La colonne "x" représente toujours le paramètre et la colonne "y" sa valeur.
    exemple2:

    z (combi)
    x (param)
    y (valeur)
    1 A a1
    1 B b1
    1 C c1
    2 A a1
    2 B b1
    2 C c2
    3 A a1
    3 B b2
    3 C c1
    4 A a1
    4 B b2
    4 C c2
    etc...
    etc...
    etc...
    12 A a3
    12 B b2
    12 C c2


    Un abapeur amateur de casse-tête connaitrait-il une solution ?
    Sachant que le nombre de paramètre ainsi que le nombre de valeurs possibles des paramètres n'est pas fixe dans le tableau.
    Je pense qu'il faut passer par un FORM recursif mais je n'ai aucune idée de par quel bout commencer (je m'embrouille assez vite avec le récursif).

    Merci d'avance, toute aide sera la bienvenue

  2. #2
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2013
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2013
    Messages : 7
    Points : 17
    Points
    17
    Par défaut
    >Un abapeur amateur de casse-tête connaitrait-il une solution ?
    L'utilisation de variables locales/abap objet pour stocker les informations d'une branche et éviter les effets de bords.
    Cela permet de conserver chaque flux récurcif indépendant.
    Les variables globales sont à limiter en temps normal, mais encore plus sur du récurcif.
    Dans l'exemple si dessous j'ai utilisé une variable statics pour la démo uniquement ; il vaut mieux les utiliser avec parcimonie.

    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
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    REPORT  z_report."  Syntaxe Abap 7.40
    
    TYPES: BEGIN OF ts_line
          , x    TYPE c
          , y(2) TYPE c
          , END OF ts_line
          , tt_std_lines TYPE STANDARD TABLE OF ts_line
                         WITH EMPTY KEY
          .
    
    *- Jump start the from
    DATA: gt_dummy TYPE tt_std_lines
        , gv_dummy TYPE sy-tabix VALUE 1
        .
    
    *- Data setup
    DATA(tab) = VALUE tt_std_lines(
                                    ( x = 'A' y = 'a1') ( x = 'A' y = 'a2') ( x = 'A' y = 'a3')
                                    ( x = 'B' y = 'b1') ( x = 'B' y = 'b2')
                                    ( x = 'C' y = 'c1') ( x = 'C' y = 'c2')
    *                                ( x = 'D' y = 'd1') ( x = 'D' y = 'd2') ( x = 'D' y = 'd3') ( x = 'D' y = 'd4') "stress test
                                  ).
    
    
    
    PERFORM loop USING gv_dummy gt_dummy.
    
    *&---------------------------------------------------------------------*
    *&      Form  LOOP
    *&---------------------------------------------------------------------*
    FORM loop USING    idx   TYPE i
                       lines TYPE tt_std_lines.
    
    
      DATA lv_first_x TYPE  c.  " Current parameter
      STATICS z TYPE i.         " Z column. Could be a global var.
    
    
    
      LOOP AT tab ASSIGNING FIELD-SYMBOL(<line>) FROM idx.
    
    *- Only process current parameter.
        IF lv_first_x IS INITIAL .
          lv_first_x = <line>-x.
    
        ENDIF .
        CHECK <line>-x EQ lv_first_x .
    
    
    *- local table = new branch in tree
        DATA(lt_lines) =  lines[] .
        APPEND <line> TO lt_lines.
    
    
    *- Start a new loop/branch starting at next parameter line
        LOOP AT tab ASSIGNING FIELD-SYMBOL(<dummy>)
                                     WHERE x EQ <line>-x.
          DATA(lv_idx) = sy-tabix .
        ENDLOOP.
        lv_idx = lv_idx + 1 . " Line index of next parameter
    
    *- If next parameter is in table range, process it
        IF lv_idx LT lines( tab ).
          PERFORM loop USING lv_idx lt_lines.
    
    
    *- If next parameter is not in table range, display branch
        ELSE.
          ADD 1 TO z.
          LOOP AT lt_lines ASSIGNING FIELD-SYMBOL(<log>).
            WRITE : / z, <log>-x, <log>-y .
    
          ENDLOOP.
          SKIP 1 .
    
        ENDIF.
    
      ENDLOOP .
    
    ENDFORM.
    Résultat :
    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
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
      1  A a1
      1  B b1
      1  C c1
    
      2  A a1
      2  B b1
      2  C c2
    
      3  A a1
      3  B b2
      3  C c1
    
      4  A a1
      4  B b2
      4  C c2
    
      5  A a2
      5  B b1
      5  C c1
    
      6  A a2
      6  B b1
      6  C c2
    
      7  A a2
      7  B b2
      7  C c1
    
      8  A a2
      8  B b2
      8  C c2
    
      9  A a3
      9  B b1
      9  C c1
    
     10  A a3
     10  B b1
     10  C c2
    
     11  A a3
     11  B b2
     11  C c1
    
     12  A a3
     12  B b2
     12  C c2

  3. #3
    Nouveau Candidat au Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2015
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2015
    Messages : 2
    Points : 1
    Points
    1
    Par défaut
    Citation Envoyé par Peter Wiggin Voir le message
    >Un abapeur amateur de casse-tête connaitrait-il une solution ?
    L'utilisation de variables locales/abap objet pour stocker les informations d'une branche et éviter les effets de bords.
    Cela permet de conserver chaque flux récurcif indépendant.
    Les variables globales sont à limiter en temps normal, mais encore plus sur du récurcif.
    Dans l'exemple si dessous j'ai utilisé une variable statics pour la démo uniquement ; il vaut mieux les utiliser avec parcimonie.
    Merci et bravo d'avoir trouvé
    Effectivement les variables statiques sont à éviter si possible.

    Entre temps j'ai trouvé une autre solution sans avoir à utiliser de fonction récursive, je la partage ici pour ceux intéressés :
    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
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    REPORT z_algorithm.
    
    TYPES: ty_param TYPE char1,
           ty_value TYPE char2,
           BEGIN OF ty_struct,
             x TYPE ty_param,
             y TYPE ty_value,
           END OF ty_struct,
           BEGIN OF ty_combi,
             z TYPE i,
             s TYPE ty_struct,
           END OF ty_combi.
    TYPES: BEGIN OF ty_param_struct,
             x  TYPE ty_param,
             ys TYPE STANDARD TABLE OF ty_value WITH DEFAULT KEY,
             ix TYPE i,
           END OF ty_param_struct.
    
    
    DATA: tab      TYPE STANDARD TABLE OF ty_struct,
          params   TYPE STANDARD TABLE OF ty_param_struct,
          done     TYPE abap_bool VALUE abap_false,
          z        TYPE i VALUE 0,
          overflow TYPE abap_bool VALUE abap_false,
          combis   TYPE STANDARD TABLE OF ty_combi.
    
    START-OF-SELECTION.
      APPEND VALUE: #( x = 'A' y = 'a1' ) TO tab,
                    #( x = 'A' y = 'a2' ) TO tab,
                    #( x = 'A' y = 'a3' ) TO tab,
                    #( x = 'B' y = 'b1' ) TO tab,
                    #( x = 'B' y = 'b2' ) TO tab,
                    #( x = 'C' y = 'c1' ) TO tab,
                    #( x = 'C' y = 'c2' ) TO tab.
    
      LOOP AT tab ASSIGNING FIELD-SYMBOL(<tab>).
        READ TABLE params WITH KEY x = <tab>-x ASSIGNING FIELD-SYMBOL(<param>).
        IF sy-subrc NE 0.
          APPEND INITIAL LINE TO params ASSIGNING <param>.
          <param>-x = <tab>-x.
          <param>-ix = 1.
        ENDIF.
        APPEND <tab>-y TO <param>-ys.
      ENDLOOP.
    
      WHILE done EQ abap_false.
    
        ADD 1 TO z.
        overflow = abap_true.
        done = abap_true.
    
        LOOP AT params ASSIGNING <param>.
    
          READ TABLE <param>-ys INDEX <param>-ix ASSIGNING FIELD-SYMBOL(<y>).
          APPEND VALUE #( z = z s-x = <param>-x s-y = <y> ) TO combis.
    
          IF overflow EQ abap_true.
            ADD 1 TO <param>-ix.
          ENDIF.
    
          IF <param>-ix GT lines( <param>-ys ).
            overflow = abap_true.
            <param>-ix = 1.
          ELSE.
            overflow = abap_false.
            done = abap_false.
          ENDIF.
    
        ENDLOOP.
    
      ENDWHILE.
    Le code vient de Gert Beukema sur StackOverflow.

Discussions similaires

  1. Réponses: 1
    Dernier message: 16/01/2014, 17h13
  2. construction de tableau en javascript
    Par paolo2002 dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 10/02/2011, 16h40
  3. Construction de tableau avec une boucle
    Par drogba72 dans le forum Langage
    Réponses: 17
    Dernier message: 25/02/2009, 07h47
  4. Construction de tableau
    Par jaussiba dans le forum Collection et Stream
    Réponses: 4
    Dernier message: 05/10/2008, 16h06
  5. Sortir d'un tableau les combinaisons possibles
    Par juelo dans le forum Algorithmes et structures de données
    Réponses: 33
    Dernier message: 26/03/2006, 17h11

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