我有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
答案 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.