如何筛选Qty和为4的MyObject列表项组合(找到即停止)
Hey there, sounds like you need to grab the first set of items from your List(Of MyObject) where the sum of their Qty properties hits your target value (4 in this case), and stop searching once you find that set. Let's work through this.
First, let's make sure we're on the same page with your existing code (I'll add the assumed MyObject class definition too, since it's needed for context):
Public Class MyObject Public Property Name As String Public Property Qty As Integer End Class Dim someValue As Integer = 4 Dim myList As New List(Of MyObject) myList.Add(New MyObject With {.Name = "N1", .Qty = 3}) myList.Add(New MyObject With {.Name = "N2", .Qty = 1}) myList.Add(New MyObject With {.Name = "N3", .Qty = 2}) myList.Add(New MyObject With {.Name = "N4", .Qty = 1})
Solution: Recursive Backtracking with Early Termination
Since you only need the first valid combination (not all possible ones), we can use a backtracking approach that stops as soon as it finds a match. This is efficient because we don't waste time checking all possible combinations once we have our result.
Here's the implementation:
Private Function FindFirstCombination(ByVal items As List(Of MyObject), ByVal targetSum As Integer) As List(Of MyObject) Dim currentCombo As New List(Of MyObject) ' Trigger the backtracking search; return the combo if found If BacktrackToFindCombo(items, targetSum, 0, currentCombo) Then Return currentCombo End If ' Return empty list if no valid combo exists Return New List(Of MyObject) End Function Private Function BacktrackToFindCombo(ByVal items As List(Of MyObject), ByVal remainingSum As Integer, ByVal startIndex As Integer, ByVal currentCombo As List(Of MyObject)) As Boolean ' We've hit our target sum - success! If remainingSum = 0 Then Return True End If ' No more items to check or we've exceeded the target - exit If remainingSum < 0 Or startIndex >= items.Count Then Return False End If ' Try including the current item in the combo currentCombo.Add(items(startIndex)) ' Recurse with the updated remaining sum and next index If BacktrackToFindCombo(items, remainingSum - items(startIndex).Qty, startIndex + 1, currentCombo) Then Return True End If ' Backtrack: remove the current item and try skipping it currentCombo.RemoveAt(currentCombo.Count - 1) ' Try skipping the current item entirely Return BacktrackToFindCombo(items, remainingSum, startIndex + 1, currentCombo) End Function
How to Use It
Call the function and process your result like this:
Dim resultCombo As List(Of MyObject) = FindFirstCombination(myList, someValue) ' Verify and output the result If resultCombo.Count > 0 Then Console.WriteLine("Found valid combination:") For Each item In resultCombo Console.WriteLine($"Name: {item.Name}, Qty: {item.Qty}") Next Console.WriteLine($"Total Qty: {resultCombo.Sum(Function(x) x.Qty)}") Else Console.WriteLine("No combination of items sums to the target value.") End If
Notes
- This implementation will return the left-most valid combo first (in your case, N1 and N2, since 3+1=4). If you wanted to prioritize a different type of combo (like the last three items N2+N3+N4 which sum to 4), you could reverse the list before passing it to the function, or adjust the backtracking order. But since you said any valid combo works once found, this default behavior should be fine.
- The backtracking approach avoids duplicate combinations by only checking items from the current
startIndexonwards, so you won't get the same items in a different order (like N2 followed by N1) as a separate combo.
内容的提问来源于stack exchange,提问作者Leebeedev

