Get Unique combination and then compute permutation
In some scenario we need to compute all possible combinations of a key field of a table to retrieve correct data from custom table, because user can maintain record in any sequence, and these key data is available in internal table format, to get all combination and for each unique combination get all
possible permutation is a challenge.
Although numbers of these combinations are huge if we go beyond 5-6 items, so be careful while implementing this solution.
Here I am sharing a code which will give unique combination in table "GT_RESULT" and for each record in "GT_RESULT" table and permutation has been calculated and kept in table "GT_RESULT2".
To understand algorithm for combination please visit to YouTube watch :
http://www.youtube.com/watch?v=p8SDPaX1wgw
I have taken reference from SCN thread for permutation logic from below link :
http://scn.sap.com/thread/18373
In my program I have implemented combination logic and call permutation logic for each combination following is the code.
*&---------------------------------------------------------------------*
*& Report Z_COMBINATION_AND_PERMUTATION
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*
REPORT Z_COMBINATION_AND_PERMUTATION.
TYPES : BEGIN OF gty_tab,
field TYPE string,
END OF gty_tab,
gtt_tab TYPE STANDARD TABLE OF gty_tab,
gtt_string TYPE TABLE OF string.
DATA : gt_initial TYPE gtt_tab,
gs_initial TYPE gty_tab,
gt_values TYPE gtt_tab,
gs_values TYPE gty_tab,
gt_result TYPE gtt_tab,
gt_result1 TYPE gtt_tab,
gt_result2 TYPE gtt_tab,
gs_result TYPE gty_tab,
level TYPE i,
max TYPE i,
gt_string TYPE TABLE OF string.
*-------Temporary Data Creation
gs_values-field = 'A' .APPEND gs_values TO gt_values.
gs_values-field = 'B' .APPEND gs_values TO gt_values.
gs_values-field = 'C' .APPEND gs_values TO gt_values.
*gs_values-field = 'D' .APPEND gs_values TO gt_values.
*gs_values-field = 'E' .APPEND gs_values TO gt_values.
*gs_values-field = 'F' .APPEND gs_values TO gt_values.
*-----Getting number of records
max = LINES( gt_values[] ).
CLEAR gs_initial.
DO max TIMES.
APPEND gs_initial TO gt_initial.
ENDDO.
level = 1.
* Internal Table GT_RESULT will return unique comination of items
PERFORM f_combination USING level
max
gt_values
CHANGING gt_initial
gt_result. " Unique Combination
write : / sy-uline(80).
write : / 'Unique Combination'.
write : / sy-uline(80).
loop at gt_result into gs_result.
write : / gs_result-field.
endloop.
clear gs_result.
*-----Logic to get all permutations
LOOP AT gt_result INTO gs_result.
SPLIT gs_result-field AT '/' INTO TABLE gt_string.
PERFORM f_permutation USING gt_string CHANGING gt_result1.
APPEND LINES OF gt_result1 to gt_result2.
ENDLOOP.
write : / sy-uline(80).
write : / 'All permutation based on above combination'.
write : / sy-uline(80).
loop at gt_result2 into gs_result.
write : / gs_result-field.
endloop.
write : / sy-uline(80).
*&---------------------------------------------------------------------*
*& Form F_COMBINATION
*&---------------------------------------------------------------------*
* Get all unique combination of provided internal table
*----------------------------------------------------------------------*
* -->P_LEVEL text
* -->P_MAX text
* -->P_GT_VALUES text
* <--P_GT_INITIAL text
* <--P_GT_RESULT text
*----------------------------------------------------------------------*
FORM f_combination USING p_level TYPE i
p_max TYPE i
pt_values TYPE gtt_tab
CHANGING pt_initial TYPE gtt_tab
pt_result TYPE gtt_tab.
FIELD-SYMBOLS : <fs1> TYPE gty_tab,
<fs_val> TYPE ANY.
DATA next_level TYPE i.
IF p_level = p_max.
READ TABLE pt_initial ASSIGNING <fs1> INDEX p_level.
CHECK <fs1> IS ASSIGNED.
CLEAR <fs1>-field.
PERFORM f_final USING pt_initial p_max
pt_values
CHANGING pt_result.
READ TABLE pt_initial ASSIGNING <fs1> INDEX p_level.
CHECK <fs1> IS ASSIGNED.
<fs1>-field = 1.
PERFORM f_final USING pt_initial p_max
pt_values
CHANGING pt_result.
RETURN.
ENDIF.
CLEAR gs_initial.
READ TABLE pt_initial ASSIGNING <fs1> INDEX p_level.
CHECK <fs1> IS ASSIGNED.
CLEAR <fs1>-field.
next_level = p_level + 1.
PERFORM f_combination USING next_level
p_max
pt_values
CHANGING pt_initial
pt_result.
READ TABLE pt_initial ASSIGNING <fs1> INDEX p_level.
CHECK <fs1> IS ASSIGNED.
<fs1>-field = 1.
PERFORM f_combination USING next_level
p_max
pt_values
CHANGING pt_initial
pt_result.
ENDFORM. " F_COMBINATION
*&---------------------------------------------------------------------*
*& Form F_FINAL
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* -->P_PT_INITIAL text
* -->P_P_MAX text
* <--P_PT_RESULT text
*----------------------------------------------------------------------*
FORM f_final USING pt_initial TYPE gtt_tab
p_max TYPE i
pt_values TYPE gtt_tab
CHANGING pt_result TYPE gtt_tab.
DATA lv_sum TYPE i.
DATA ls_line LIKE LINE OF pt_initial.
DATA ls_values LIKE LINE OF pt_values.
DATA ls_result LIKE LINE OF pt_result.
CLEAR lv_sum.
LOOP AT pt_initial INTO ls_line.
IF NOT ls_line IS INITIAL.
READ TABLE pt_values INTO ls_values INDEX sy-tabix.
IF sy-subrc IS INITIAL.
IF ls_result-field IS INITIAL.
ls_result-field = ls_values-field.
ELSE.
CONCATENATE ls_result-field ls_values-field INTO
ls_result-field SEPARATED BY '/'.
ENDIF.
ENDIF.
ENDIF.
ENDLOOP.
APPEND ls_result TO pt_result.
ENDFORM. " F_FINAL
*&---------------------------------------------------------------------*
*& Form F_PERMUTATION
*&---------------------------------------------------------------------*
* To get all permutation of given table
*----------------------------------------------------------------------*
* -->P_GT_STRING text
* <--P_GT_RESULT1 text
*----------------------------------------------------------------------*
FORM f_permutation USING pt_string TYPE gtt_string
CHANGING pt_result1 TYPE gtt_tab.
DATA: lt_string TYPE TABLE OF string,
lt_result TYPE gtt_tab,
lv_tabix LIKE sy-tabix,
ls_string TYPE string,
ls_result LIKE LINE OF pt_result1.
refresh pt_result1.
DESCRIBE TABLE pt_string LINES lv_tabix.
IF lv_tabix <= 1.
LOOP AT pt_string INTO ls_string.
ls_result-field = ls_string.
APPEND ls_result TO pt_result1.
ENDLOOP.
ELSE.
DO lv_tabix TIMES.
lt_string = pt_string.
READ TABLE pt_string INTO ls_string INDEX sy-index.
DELETE lt_string INDEX sy-index.
PERFORM f_permutation USING lt_string
CHANGING lt_result.
LOOP AT lt_result INTO ls_result.
CONCATENATE ls_string ls_result-field INTO ls_result-field
SEPARATED BY '/'.
APPEND ls_result TO pt_result1.
ENDLOOP.
ENDDO.
ENDIF.
ENDFORM. " F_PERMUTATION
Output for this program for 3 table entries 'A' 'B'and 'C' is :
Thanks and Regards,
Gagan Choudha