• 5

(6/28 小更新)Excel多組數字挑選加總為指定數值的方法(vba 範例)

nezher wrote:
比如100只有一個 那後面的排列不要再出現100


原來20組,去掉重複的剩7組,是這樣嗎??



把這一行
If tempsum = target Then

改成
If tempsum = target And IsError(Application.Match(targetsum(1), Range("g:g"), 0)) Then
ren1244 wrote:
稍微看了一下程式
假設資料原本是 500, 400, 300, 200, 100
目標數值是 700
程式計算到 500 + 400 時
不會判斷數值已經超過了,會繼續往下測試 500 + 400 + 300 等數值
這會浪費很多計算時間
感覺可以優化加快速度


排列組合是用"位置"來處理的
先有排列組合的結果,這時再看內容,才能用條件判斷要不要
我試過先判斷內容再處理,結果時間更長,很想再優化,可惜能力有限

要快只能在=>最大搜尋組數,填入1組
有所有可能解中,找到1組就中斷計算
excel內建的規劃求解,也是類似的作法,只找1組可能解,其它忽略不計
我手邊沒有 MS Office
所以用 html + javascript 做個範例

如下圖,第一組(20個數字)只要測試 624457 個組合就夠了


第二組(23個數字)甚至只要測試 338707 個組合,比先前更少
(計算量的多寡受數字分布的影響,所以數字多的未必計算量會更多)

完整程式如附件: [點擊下載]

核心程式碼

function findCombine(data, target) {
data = data.sort((a, b) => b - a); //複製並排序
let stack = [], stackIdx = 0; //堆疊
let idx = 0; //目前應該讀取 data 的位置
let sumVal = 0, val; //總和
let result = []; //結果
let testCount = 0; //計算共測試了幾個數字
while (idx < data.length || stackIdx > 0) {
//如果沒資料了則退回,找下一個
if (idx >= data.length) {
let topIdx = stack[--stackIdx];
sumVal -= data[topIdx];
idx = topIdx + 1;
continue;
}
//加入 data[idx]
stack[stackIdx++] = idx;
sumVal += (val = data[idx++]);
++testCount;
//若符合則記錄,超過則退回
if (sumVal === target) {
let tmp = [];
for (let i = 0; i < stackIdx; ++i) {
tmp.push(data[stack[i]]);
}
result.push(tmp);
} else if (sumVal > target) {
--stackIdx;
sumVal -= val;
}
}
return {result, testCount};
}


PS. 這邊主要是展示算法,直接求所有答案,細部設定之後可再加上去
ren1244 wrote:
所以用 html + javascript 做個範例
如下圖,第一組(20個數字)只要測試 624457 個組合就夠了


感謝ren1244 您這位高手,願意抽空寫範例的指導我,讓我功力又進步了一些

參考您的範例後,簡單改寫一下vba
先排序後,再去掉加總大於目標值不要計算

用您的20個數字測試
沒修改前1048575次,約5秒
修改後761509次,約1.6秒,
本來以為不能再快了,沒想到用您的方法,又快了3倍





雖然離您精簡的計算次數,還有一大段距離,但我不想改了
因為看到javascript 同樣的東西,只要算8ms
而試了vba用最精簡的寫法,只是單純跑迴圈624457次,都要76ms
每加一行程式碼,處理時間就會再增加
跟演算法無關,是先天上的限制
認命了,怎麼改都不可能贏過javascript ,連效能接近一點都辦不到




'(不可重複選取的不重複組合公式)
'簡單修改後程式碼,有點亂,修修補補的,不想整理了


Sub test()

Dim data(), targetsum() As Double, item_name() As String, lastrow As Integer, ttt As Double
Dim total As Long, i As Integer, ok As Integer, target As Double, limited As Integer, maxcombin As Integer, start As Integer, startend As Integer, tolerance As Double, rs As Boolean

Columns("E:Z").Clear

On Error GoTo Esc_Stop
Application.EnableCancelKey = xlErrorHandler

ttt = Timer

lastrow = Range("A2").End(xlDown).Row
ReDim data(1 To 2, 1 To lastrow - 1)
data(1, 1) = Cells(2, 2).Value

For d = 1 To lastrow - 1
data(1, d) = Cells(d + 1, 2).Value
Next d

For d = 1 To UBound(data, 2) - 1
For e = d + 1 To UBound(data, 2)
If data(1, d) > data(1, e) Then
temp = data(1, d)
data(1, d) = data(1, e)
data(1, e) = temp
End If
Next e
Next d

If Range("C1") = 0 Then End

target = Range("C1"): tolerance = Range("C2"): limited = Range("C3"): maxcombin = Range("C4")
Range("C5") = "": Range("C8") = "": Range("E1") = Format(Now(), "hh:mm:ss")

If Range("c6") = "" Then
Range("c6") = False
Range("c7") = ""
End If

If Range("c6") = True And Range("c7") = "" Then Range("c7") = 15

rs = Range("c6")

If limited = 0 Then
start = 1
If rs = True Then
startend = Range("c7")
Else
For d = 1 To UBound(data, 2)
f = f + data(1, d)
If f > target Then Exit For
Next d
startend = d - 1
End If
Else
start = limited: startend = start
End If

For i = start To startend
ReDim targetsum(1 To i)
Call findCombin(data, targetsum, item_name, i, total, 1, 1, ok, target, limited, maxcombin, tolerance, rs)
If start <> startend Then Range("C8") = Int((i / startend * 100) + 0.5) & "%請耐心等待"
Next i

If ok <> 0 Then Call find_name

Range("C8") = "100%計算結束": Range("E2") = Format(Now(), "hh:mm:ss")
Debug.Print total, Timer - ttt

Exit Sub

Esc_Stop:
If Err = 18 Then
MsgBox "stop"
End If

End Sub

Sub findCombin(data(), targetsum() As Double, item_name() As String, j As Integer, total As Long, k As Integer, n As Integer, ok As Integer, target As Double, limited As Integer, maxcombin As Integer, tolerance As Double, rs As Boolean)

Dim i As Integer, tempsum As Double

For i = k To UBound(data, 2)
targetsum(n) = data(1, i): tempsum = 0
If n = j Then

total = total + 1

For s = 1 To UBound(targetsum)
tempsum = tempsum + targetsum(s)
If tempsum > target Then Exit Sub
Next s

If tempsum = target Then
ok = ok + 1
Range("G" & ok).Resize(1, j) = targetsum
If (ok = maxcombin And maxcombin <> 0) Then
Range("C5") = ok: Range("C8") = "100%計算結束": Range("E2") = Format(Now(), "hh:mm:ss"): Debug.Print total
If ok <> 0 Then Call find_name
End
End If

Range("c5") = ok

Exit Sub
End If
Else
Call findCombin(data, targetsum, item_name, j, total, i + IIf(rs, 0, 1), n + 1, ok, target, limited, maxcombin, tolerance, rs)
End If
Next i

End Sub

Sub find_name()

Dim lastrow As Integer, lastcol As Integer, n As Object, name_data() As String
Set n = CreateObject("Scripting.Dictionary")
Application.ScreenUpdating = False

lastrow = Range("A1").End(xlDown).Row
For i = 2 To lastrow
n.Add Str(Cells(i, 2)), Cells(i, 1)
Next i

For i = 1 To Range("c5").Value
lastcol = Range("G" & i).End(xlToRight).Column
ReDim name_data(1 To lastcol - 6)

For j = 7 To lastcol
name_data(j - 6) = n(Str(Cells(i, j)))
Next j

Cells(i, 6) = Join(name_data, ",")

Next i

Set n = Nothing
Application.ScreenUpdating = True

End Sub

下面這段我覺得還可以優化啦
For i = start To startend
ReDim targetsum(1 To i)
Call findCombin(data, targetsum, item_name, i, total, 1, 1, ok, target, limited, maxcombin, tolerance, rs)
If start <> startend Then Range("C8") = Int((i / startend * 100) + 0.5) & "%請耐心等待"
Next i

舉例來說 i = 3 時,呼叫 findCombin 也是從 i = 1, 2... 開始產生組合
所以前面的 i 會重複很多次

要達成這種功能我會直接寫在 findCombin 函數裡面
javascript 程式碼修改如下
(這邊順邊加上要不要得到一個解就終止的功能)
function findCombine(data, target, minItem, maxItem, oneSolution) {
data = data.sort((a, b) => b - a); //複製並排序
let stack = [], stackIdx = 0; //堆疊
let idx = 0; //目前應該讀取 data 的位置
let sumVal = 0, val; //總和
let result = []; //結果
let testCount = 0; //計算共測試了幾個數字
while (idx < data.length || stackIdx > 0) {
//如果沒資料或超過允許選取個數,則退回,找下一個
if (idx >= data.length || stackIdx>=maxItem) {
let topIdx = stack[--stackIdx];
sumVal -= data[topIdx];
idx = topIdx + 1;
continue;
}
//加入 data[idx]
stack[stackIdx++] = idx;
sumVal += (val = data[idx++]);
++testCount;
//若符合則記錄,超過則退回
if (sumVal === target) {
if(stackIdx >= minItem) {
let tmp = [];
for (let i = 0; i < stackIdx; ++i) {
tmp.push(data[stack[i]]);
}
result.push(tmp);
//如果只需要1解,有1解就終止
if(oneSolution && result.length>0) {
break;
}
} else {
--stackIdx;
sumVal -= val;
}
} else if (sumVal > target) {
--stackIdx;
sumVal -= val;
}
}
return {result, testCount};
}

跟上個版本比對


完整檔案如附件:[點擊下載]
ren1244 wrote:
下面這段我覺得還可以優化啦
For i = start To startend
ReDim targetsum(1 To i)
Call findCombin(data, targetsum, item_name, i, total, 1, 1, ok, target, limited, maxcombin, tolerance, rs)
If start <> startend Then Range("C8") = Int((i / startend * 100) + 0.5) & "%請耐心等待"
Next i

舉例來說 i = 3 時,呼叫 findCombin 也是從 i = 1, 2... 開始產生組合
所以前面的 i 會重複很多次



6年前寫這個範例時,是翻出學校課本,臨時惡補以前所學
照著這個公式 c(n,m)=n!/((n-m)!m!),一層一層拆解,改寫成vba
從來沒注意到從頭算到尾的方式,有太多沒用的計算
人工驗算後,確實有多餘的運算在浪費時間,多加一些if,還可省掉不少計算

可惜vba效能輸javascript太多,就算優化到同樣的計算次數
還是比不上您的javascript範例8ms

感謝您的指導、教學
因為沒有 Microsoft Office
所以試著用 Libre Office 寫看看

Libre Office 允許多種不同語言製作巨集
使用相同的算法,分別製作了 basic 與 python 版本測試



以 23 組數據的那個例子
basic:共測試 338707 個組合, 得到 180 個解, 花費計算 6731 毫秒, 寫入 45 毫秒
python:共測試 338707 個組合, 得到 180 個解, 花費計算 125 毫秒, 寫入 16 毫秒

發現兩者速度差滿多的

basic 慢不是算法的問題
因為 Libre Office 的 basic 連以下這樣的程式都要執行 919 毫秒

Sub TestSpeed()
Dim i As Long
Dim j As Long
Dim t As Long
t = GetSystemTicks()
For i = 1 To 624457
j = j + 1
Next i
MsgBox "執行" & (GetSystemTicks() - t) & "毫秒"
End Sub


檔案如附件:[點擊下載]

basic 版本程式碼
(應該滿容易改成給 Microsoft Office 使用)

Type DataType
Val As Double '數值
Lab As String '標籤
End Type

Sub Main
' 目前開啟的頁面
Dim sheet As Object
sheet = ThisComponent.CurrentController.ActiveSheet

' 清除舊資料
sheet.getCellRangeByPosition(5, 0, sheet.getColumns().Count - 1, sheet.getRows().Count - 1).clearContents(1023)

' 讀取資料到陣列
Dim lastIndex As Long
lastIndex = getEndOfColumn(sheet, 1) ' 資料在 1~lastIndex 列
Dim data(lastIndex - 1) As DataType
For iRow=1 To lastIndex
data(iRow - 1).Val = sheet.getCellByPosition(1, iRow).Value
data(iRow - 1).Lab = sheet.getCellByPosition(0, iRow).String
Next iRow

' 排序
QuickSort(data, 0, lastIndex - 1)

' 讀取設定
Dim target As Double, minItem As Long, maxItem As Long, oneSol As Long
target = readAsValue(sheet, 3, 1, -1)
minItem = readAsValue(sheet, 3, 2, 1)
maxItem = readAsValue(sheet, 3, 3, lastIndex)
oneSol = readAsValue(sheet, 3, 4, 0)

' 尋找組合
Dim t0 As Long, t1 As Long, t2 As Long, CombinResult As Variant
Dim nCombins As Long, nSolutions As Long, resultArr As Variant, maxLen As Long
Dim outputData() As Variant, maxIdx As Long, str As String
t0 = GetSystemTicks()
If target > 0 Then
CombinResult = findTheCombin(data, lastIndex, target, minItem, maxItem, oneSol)
t1 = GetSystemTicks()
nCombins = CombinResult(0)
nSolutions = CombinResult(1)
resultArr = CombinResult(2)
maxLen = CombinResult(3)
Redim outputData(nSolutions - 1, maxLen)
For i = 0 To nSolutions - 1
maxIdx = UBound(resultArr(i))
str = ""
For j = 0 To maxLen
If j > maxIdx + 1 Then
outputData(i, j) = ""
ElseIf j > 0 Then
outputData(i, j) = data(resultArr(i)(j - 1)).Val
If j = 1 Then
str = data(resultArr(i)(j - 1)).Lab
Else
str = str & ", " & data(resultArr(i)(j - 1)).Lab
End If
Else
outputData(i, j) = ""
End If
Next j
outputData(i, 0) = str
Next i
sheet.getCellRangeByPosition(5, 1, 5 + maxLen, nSolutions).DataArray = outputData
t2 = GetSystemTicks()
sheet.getCellByPosition(5, 0).String = "共測試 " & nCombins & " 個組合, 得到 " & nSolutions & " 個解, 花費計算 " & (t1-t0) & " 毫秒, 寫入 " & (t2-t1) & " 毫秒"
End If
End Sub

Function findTheCombin(data() AS DataType, n As Long, target As Double, minItem As Long, maxItem As Long, oneSol As Long)
'紀錄使用 data index 的堆疊
Dim stack(n) As Long, stackIdx As Long, sumVal(n) as Double
sumVal(0) = 0
stackIdx = 1
'目前應該讀取 data 的位置
Dim idx As Long
idx = 0
'計算共測試了幾個組合
Dim testCount As Long
testCount = 0
'輸出使用
Dim result() As Variant, resultIdx As Long, resultSize As Long, resultTemp() As Long, maxLen As Long
resultSize = 4
resultIdx = 0
maxLen = 0
Redim result(resultSize - 1)
'其他暫存變數
Dim k As Long

Do While idx < n Or stackIdx > 1
'如果沒資料或超過允許選取個數,則退回,找下一個
If idx >= n Or stackIdx > maxItem Then
stackIdx = stackIdx - 1
idx = stack(stackIdx) + 1
Else
'加入 data[idx]
stack(stackIdx) = idx
sumVal(stackIdx) = sumVal(stackIdx - 1) + data(idx).Val
stackIdx = stackIdx + 1
idx = idx + 1
testCount = testCount + 1
' 若符合則記錄,超過則退回
If sumVal(stackIdx - 1) = target Then
If stackIdx > minItem Then
' 紀錄
Redim resultTemp(stackIdx - 2)
If maxLen < stackIdx - 1 Then
maxLen = stackIdx - 1
End If
For k = 1 To stackIdx - 1
resultTemp(k - 1) = stack(k)
Next k
If resultIdx >= resultSize Then
resultSize = resultSize * 2
Redim Preserve result(resultSize - 1)
End If
result(resultIdx) = resultTemp
resultIdx = resultIdx + 1
' 如果只需要1解,有1解就終止
If oneSol > 0 Then
Exit Do
End If
Else
stackIdx = stackIdx - 1
End If
ElseIf sumVal(stackIdx - 1) > target Then
stackIdx = stackIdx - 1
End If
End If
Loop
findTheCombin = Array(testCount, resultIdx, result, maxLen)
End Function

' 取得某行最後一筆資料的索引
Function getEndOfColumn(sheet As Object, colIndex As Long)
Dim n As Long, tp As Long
n = 0
Do
n = n + 1
tp = sheet.getCellByPosition(colIndex, n).getType()
Loop While tp <> com.sun.star.table.CellContentType.EMPTY
getEndOfColumn = n - 1
End Function

' 排序
Sub QuickSort(vArray As DataType, inLow As Long, inHi As Long)
Dim pivot As DataType
Dim tmpSwap As DataType
Dim tmpLow As Long
Dim tmpHi As Long

tmpLow = inLow
tmpHi = inHi

pivot.Val = vArray((inLow + inHi) \ 2).Val
pivot.Lab = vArray((inLow + inHi) \ 2).Lab


While (tmpLow <= tmpHi)
While (vArray(tmpLow).Val > pivot.Val And tmpLow < inHi)
tmpLow = tmpLow + 1
Wend

While (pivot.Val > vArray(tmpHi).Val And tmpHi > inLow)
tmpHi = tmpHi - 1
Wend

If (tmpLow <= tmpHi) Then
tmpSwap.Val = vArray(tmpLow).Val
tmpSwap.Lab = vArray(tmpLow).Lab
vArray(tmpLow).Val = vArray(tmpHi).Val
vArray(tmpLow).Lab = vArray(tmpHi).Lab
vArray(tmpHi).Val = tmpSwap.Val
vArray(tmpHi).Lab = tmpSwap.Lab
tmpLow = tmpLow + 1
tmpHi = tmpHi - 1
End If
Wend

If (inLow < tmpHi) Then QuickSort vArray, inLow, tmpHi
If (tmpLow < inHi) Then QuickSort vArray, tmpLow, inHi
End Sub

Function readAsValue(sheet As Object, iCol As Long, iRow As Long, defaultVal As Long)
Dim cell As Object
cell = sheet.getCellByPosition(iCol, iRow)
if cell.getType() = com.sun.star.table.CellContentType.VALUE Then
readAsValue = cell.Value
Else
readAsValue = defaultVal
End If
End Function

Sub TestSpeed()
Dim i As Long
Dim j As Long
Dim t As Long
t = GetSystemTicks()
For i = 1 To 624457
j = j + 1
Next i
MsgBox "執行" & (GetSystemTicks() - t) & "毫秒"
End Sub
ren1244 wrote:
以 23 組數據的那個例子
basic:共測試 338707 個組合, 得到 180 個解, 花費計算 6731 毫秒, 寫入 45 毫秒
python:共測試 338707 個組合, 得到 180 個解, 花費計算 125 毫秒, 寫入 16 毫秒

發現兩者速度差滿多的

basic 慢不是算法的問題
因為 Libre Office 的 basic 連以下這樣的程式都要執行 919 毫秒


感謝您又另外提供basic、python範例
basic沒問題,但python我目前只是看的懂的初學者

用24樓那個被javascript的效能打擊到,暫時不想優化的程式測試
23 組數據
vba:共測試1338955 個組合,得到180個解,總花費約3000毫秒




目前速度上javascript>python>>>遠大於>>>vba>basic
效能是各種不同程式語言先天上體質的問題,看來這部份無解

發現一件高興的事,那就是舊版vba無效的多餘計算還很多
由此可知,我的進步空間還很大

但我從來沒用過 Libre Office 寫程式
不過語法都是以basic為基礎,有9成像vba
等假日稍微惡補一下不同處就能改寫了,有空再改寫

再次感謝您的指導
我也是覺得好玩寫一下
寫到這樣暫時也不會有新本版了

關於語言的問題
應該也跟運行的平台有關
例如不同瀏覽器下跑相同的 javascript 也會有不同的結果
而 MS Office 跟 Libre Office 執行 Basic 的速度也是有差異
ren1244 wrote:
而 MS Office 跟 Libre Office 執行 Basic 的速度也是有差異


花了幾天練習一下Libre Office vb
改寫時發現您寫的範例很完美,9成的程式碼可以直接套到用vba
我只有修改約1成,只花了少少的15分鐘,就移植到excel了

特別的是,您的演算法,非常適合用在excel
雖然比不上java,但同樣的23組,計算只要0.1秒,比python還快
比起來我那拆解公式的方式只能算窮舉法、暴力解法,連演算都沾不上邊


在我的舊文書電腦上(計算時間是您的2倍)
Libre Office vb ,大約13秒




Libre Office python ,大約0.3秒




excel vba ,大約0.1秒




Sub Main()

'此範例、高速演算法是 mobile01 ren1244 高手作品
'我只有簡單改寫LibreOffice vb to Excel VBA,修正少數幾行程式碼相容性問題


' 清除舊資料
Columns("E:Z").Clear

' 讀取資料到陣列
Dim lastIndex As Long, data(), ttt As Double
lastIndex = Range("A2").End(xlDown).Row - 1
ReDim data(1, lastIndex - 1)

For iRow = 1 To lastIndex

data(0, iRow - 1) = Cells(iRow + 1, 2).Value
data(1, iRow - 1) = Cells(iRow + 1, 1).Value

Next iRow

' 排序


For d = 0 To UBound(data, 2) - 1
For e = d + 1 To UBound(data, 2)
If data(0, d) < data(0, e) Then
temp0 = data(0, d)
temp1 = data(1, d)
data(0, d) = data(0, e)
data(1, d) = data(1, e)
data(0, e) = temp0
data(1, e) = temp1
End If
Next e
Next d


ttt = Timer


' 讀取設定
Dim target As Double, minItem As Long, maxItem As Long, oneSol As Long
target = Range("d2")
minItem = IIf(Range("d3") = "", 1, Range("d3"))
maxItem = IIf(Range("d4") = "", lastIndex, Range("d4"))
oneSol = IIf(Range("d5") = "", 0, Range("d5"))

' 尋找組合
Dim t0 As Long, t1 As Long, t2 As Long, CombinResult As Variant
Dim nCombins As Long, nSolutions As Long, resultArr As Variant, maxLen As Long
Dim outputData() As Variant, maxIdx As Long, str As String

If target > 0 Then
CombinResult = findTheCombin(data, lastIndex, target, minItem, maxItem, oneSol)

nCombins = CombinResult(0)
nSolutions = CombinResult(1)
resultArr = CombinResult(2)
maxLen = CombinResult(3)
ReDim outputData(nSolutions - 1, maxLen)
For i = 0 To nSolutions - 1
maxIdx = UBound(resultArr(i))
str = ""
For j = 0 To maxLen
If j > maxIdx + 1 Then
outputData(i, j) = ""
ElseIf j > 0 Then
outputData(i, j) = data(0, resultArr(i)(j - 1))
If j = 1 Then
str = data(1, resultArr(i)(j - 1))
Else
str = str & ", " & data(1, resultArr(i)(j - 1))
End If
Else
outputData(i, j) = ""
End If
Next j
outputData(i, 0) = str
Next i

Range("f2").Resize(nSolutions, maxLen) = outputData
Range("f1") = "共測試 " & nCombins & " 個組合, 得到 " & nSolutions & " 個解, 花費計算 " & Timer - ttt & " 秒"

End If

End Sub

Function findTheCombin(data(), n As Long, target As Double, minItem As Long, maxItem As Long, oneSol As Long)
'紀錄使用 data index 的堆疊
Dim stack(), stackIdx As Long, sumVal()
ReDim stack(n)
ReDim sumVal(n)
sumVal(0) = 0
stackIdx = 1
'目前應該讀取 data 的位置
Dim idx As Long
idx = 0
'計算共測試了幾個組合
Dim testCount As Long
testCount = 0
'輸出使用
Dim result() As Variant, resultIdx As Long, resultSize As Long, resultTemp() As Long, maxLen As Long
resultSize = 4
resultIdx = 0
maxLen = 0
ReDim result(resultSize - 1)
'其他暫存變數
Dim k As Long

Do While idx < n Or stackIdx > 1
'如果沒資料或超過允許選取個數,則退回,找下一個
If idx >= n Or stackIdx > maxItem Then
stackIdx = stackIdx - 1
idx = stack(stackIdx) + 1
Else
'加入 data[idx]
stack(stackIdx) = idx
sumVal(stackIdx) = sumVal(stackIdx - 1) + data(0, idx)
stackIdx = stackIdx + 1
idx = idx + 1
testCount = testCount + 1
' 若符合則記錄,超過則退回
If sumVal(stackIdx - 1) = target Then
If stackIdx > minItem Then
' 紀錄
ReDim resultTemp(stackIdx - 2)
If maxLen < stackIdx - 1 Then
maxLen = stackIdx - 1
End If
For k = 1 To stackIdx - 1
resultTemp(k - 1) = stack(k)
Next k
If resultIdx >= resultSize Then
resultSize = resultSize * 2
ReDim Preserve result(resultSize - 1)
End If
result(resultIdx) = resultTemp
resultIdx = resultIdx + 1
' 如果只需要1解,有1解就終止
If oneSol > 0 Then
Exit Do
End If
Else
stackIdx = stackIdx - 1
End If
ElseIf sumVal(stackIdx - 1) > target Then
stackIdx = stackIdx - 1
End If
End If
Loop
findTheCombin = Array(testCount, resultIdx, result, maxLen)
End Function





感謝ren1244的教學
[點擊下載]
mlchen21456

感謝snare提供的EXCEL 巨集,我發現一個bug 用只需一解(空白視為0) 列出來的資料會少一個,我不懂程式碼要如何修改,不知道大大有沒有時間修改

2022-11-17 22:31
SUPPLY89

想請問大大這程式碼,該如何增加你上一個程式碼的誤差值呢??

2024-01-10 15:18
  • 5
內文搜尋
X
評分
評分
複製連結
Mobile01提醒您
您目前瀏覽的是行動版網頁
是否切換到電腦版網頁呢?