有谁知道如何在COBOL中编写此算法:sum数组值,其总和等于X.

时间:2015-03-24 23:02:08

标签: algorithm cobol

我有12个会计金额与此顺序中的两个不同发票相关联:-18.91,-8.48,-3654.47,-3379.07,-648.91,-2025.30,-1121.27,-1132.26,-22.68,-324.45,-861.50 ,和-24.31;其中,这些会计金额的组合等于发票金额-8574.87;剩余金额应等于其他发票金额-4646.74。是否有一个可以用COBOL编写的数学公式来确定这个结果。

01 Acct表值空间。    05 acct-entry发生50次        10 acct-amt PIC S9(12)V99

01发票 - 表格值空格。     05 inv-entry发生50次         10 inv-amt PIC S9(12)V99

1 个答案:

答案 0 :(得分:2)

有2 ^ 12种不同的帐户组合。暴力方法 可以使用位掩码实现所有组合。(COBOL实现 将不是那么直接),一个近似的伪代码 获得如下概述。

for b=0 to 2^12 - 1 do #each combination

  sum1 = 0
  sum2=  0
  for i=0 to 11 do   # which elements are included

     if (b && (1<<i) != 0)
        sum1 = sum1+ arr[i+1]
     else
        sum2 = sum2+ arr[i+1] 
    end
  end
  if (sum1= -8574.87 and sum2= -4646.74)
       print "got it"
  end
end

Cobol实现它(使用Web编译器编译和测试的freeformat)。手动计算位掩码/位位置(通过重复除以2并取余数)。 以下组合就是答案: -8,48 + -3379,07 + -2025,30 + -1121,27 + -1132,26 + -22,68 + -861,50 + -24,31

IDENTIFICATION DIVISION.
PROGRAM-ID. ACCSUM.
DATA DIVISION.
WORKING-STORAGE SECTION.
01  ACCOUNTS.
    05  ACC-X       PIC S9(4)v99 COMP-3 
                    OCCURS 12 TIMES.
01  B               PIC 9(06) comp.
01  bx              PIC 9(06) comp.
01  pos             pic 9(06) comp.
01  sum1            pic s9(8)v99 comp-3.
01  sum2            pic s9(8)v99 comp-3.
01  r               pic 9(06) comp.
01  res             pic 9(06) comp. 
01  comb            pic x(15) value space.

PROCEDURE DIVISION.
0000-MAIN SECTION.
    PERFORM 0100-init
    perform 0200-process
    STOP RUN.
0100-init section.
    move  -18.91  to ACC-X(1)
    move  -8.48   to ACC-X(2)
    move  -3654.47 to ACC-X(3)
    move   -3379.07 to ACC-X(4)
    move   -648.91 to ACC-X(5)
    move  -2025.30 to ACC-X(6)
    move  -1121.27 to ACC-X(7)
    move  -1132.26 to ACC-X(8)
    move  -22.68 to ACC-X(9)
    move  -324.45 to ACC-X(10)
    move  -861.50 to ACC-X(11)
    move  -24.31 to ACC-X(12)
    exit.
0200-process section.

    perform varying b from 0 by 1
      until b>4095
       compute bx=b
       compute pos=0
       move zero to sum1 sum2
       perform until bx= zero
            divide bx by 2 giving res remainder r

            if ( r <> zero )
              compute sum1 = sum1+ acc-x ( pos + 1 )
              move '1' to comb(pos + 1 : 1)
            else
              compute sum2 = sum2+ acc-x ( pos + 1 )
              move '0' to comb(pos + 1 : 1)
            end-if

            compute bx = bx / 2
            add 1 to pos

       end-perform

       if (sum1 = -8574.87 ) then
         display "combination :" comb "-Sum2=" sum2
       end-if
    end-perform
    exit.