ABAP算法:找出递归的物料

来源:互联网 发布:方鸿渐和小姐 知乎 编辑:程序博客网 时间:2024/05/17 07:55
今天有人在群里问了这样一个问题,一个内表有2个字段:f1和f2,每个条目代表物料f1消耗了f2。有一种可能是,f1消耗了f2,f2直接或间接又消耗了f1,形成一种递归关系。
现在希望找出内表中所有的这种物料,因为这些物料对成本分摊有不良影响。比如:[a,b] [b,c] [a,d] [b,d] [c,a];则结果包含a,b,c,不包含d。乍一看需求有点晕,仔细一想,其实就是将内表中所有条目,两两之间进行运算而已。
程序思路:每次取内表中的一个条目,将它与内表中位于其前面的所有条目进行运算;运算过程中,如果生成了新对应关系,则将其添加到内表后面(也等待着与内表中所有条目进行运算);如此循环……等到内表循环结束,所有可能的对应关系,自然都被考虑到了。

DATABEGIN OF wa1,
        f1 TYPE c,
        f2 TYPE c,
      END OF wa1.

DATA: wa2 LIKE wa1,
      tabix LIKE sy-tabix,
      itab LIKE TABLE OF wa1 WITH HEADER LINE,
      itab2 TYPE TABLE OF c WITH HEADER LINE.

itab-f1 = 'a'.
itab-f2 = 'b'.
APPEND itab.
itab-f1 = 'b'.
itab-f2 = 'c'.
APPEND itab.
itab-f1 = 'a'.
itab-f2 = 'd'.
APPEND itab.
itab-f1 = 'b'.
itab-f2 = 'd'.
APPEND itab.
itab-f1 = 'c'.
itab-f2 = 'a'.
APPEND itab.

LOOP AT itab INTO wa1.
  tabix = sy-tabix - 1.
  LOOP AT itab INTO wa2 TO tabix.
    IF wa2-f2 = wa1-f1. "运算一
      READ TABLE itab WITH KEY
        f1 = wa2-f1 f2 = wa1-f2.
      IF sy-subrc <> 0.
        IF wa2-f1 = wa1-f2.
          APPEND wa2-f1 TO itab2. "存到结果表
        ELSE.
          itab-f1 = wa2-f1.
          itab-f2 = wa1-f2.
          APPEND itab. "添加新对应关系到内表
        ENDIF.
      ENDIF.
    ENDIF.
    IF wa2-f1 = wa1-f2. "运算二
      READ TABLE itab WITH KEY
        f1 = wa1-f1 f2 = wa2-f2.
      IF sy-subrc <> 0.
        IF wa1-f1 = wa2-f2.
          APPEND wa1-f1 TO itab2. "存到结果表
        ELSE.
          itab-f1 = wa1-f1.
          itab-f2 = wa2-f2.
          APPEND itab. "添加新对应关系到内表
        ENDIF.
      ENDIF.
    ENDIF.
  ENDLOOP.
ENDLOOP.

SORT itab2.
DELETE ADJACENT DUPLICATES FROM itab2.
LOOP AT itab2. "输出结果表
  WRITE: / itab2.
ENDLOOP.
LOOP AT itab. "输出所有对应关系作参考
  WRITE: / itab-f1, itab-f2.
ENDLOOP.

程序运行过程:
1,[a,b][b,c][a,d][b,d][c,a],他们相互间运算完毕后,生成了新对应关系[a,c][c,b][b,a][c,d];
2,[a,c][c,b][b,a][c,d]这些新对应关系与老对应关系两两运算,同时相互间也两两运算,生成了新对应关系[c,c][a,a][b,b]。这是特殊的对应关系(即递归关系),它们不需要重新参与运算,直接写到了我们的结果表。
由于没有新对应关系的生成,程序运行完毕,结果表中形成了a,b,c三条记录。