我应该如何设置条件,只显示1,2、3、4或5个数字的变体。
Function SumUpRecursive(numbers As List(Of Integer), target As Integer, part As List(Of Integer), solutions As List(Of List(Of Integer))) As List(Of List(Of Integer))
Dim s = part.Sum()
If s = target Then
' MsgBox("sum(" & String.Join(",", part.[Select](Function(n) n.ToString()).ToArray()) & ")=" & target)
solutions.Add(part)
End If
If s >= target Then
Return Nothing
End If
For i As Integer = 0 To numbers.Count - 1
Dim remaining = New List(Of Integer)()
Dim n As Integer = numbers(i)
For j As Integer = i + 1 To numbers.Count - 1
remaining.Add(numbers(j))
Next
Dim part_rec = New List(Of Integer)(part)
part_rec.Add(n)
SumUpRecursive(remaining, target, part_rec, solutions)
Next
Return solutions
End Function
按钮:
Dim numbers As Integer() = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72,
73, 74, 75, 76, 77, 78, 79, 80}
Dim target As Integer = 15
Dim nums = SumUpRecursive((numbers.ToList()), target, New List(Of Integer), New List(Of List(Of Integer)))
If nums Is Nothing Then
MsgBox("Failure :(")
Else
TxtListScanTxt.Lines = nums.Select(Function(b) String.Join(", ", b)).ToArray()
End If
输出:
1, 2, 3, 4, 5
1, 2, 3, 9
1, 2, 4, 8
1, 2, 5, 7
1, 2, 12
1, 3, 4, 7
1, 3, 5, 6
1, 3, 11
1, 4, 10
1, 5, 9
1, 6, 8
1, 14
2, 3, 4, 6
2, 3, 10
2, 4, 9
2, 5, 8
2, 6, 7
2, 13
3, 4, 8
3, 5, 7
3, 12
4, 5, 6
4, 11
5, 10
6, 9
7, 8
15
我只想显示3个组合(仅显示3位数字)。
3, 4, 8
3, 5, 7
4, 5, 6
以此类推...
我如何改进代码来做到这一点?仅计算3、4或5的组合,而不是全部。因为否则程序会崩溃,因此组合太多。大量。
答案 0 :(得分:1)
添加一些重载来帮助
模块中的代码:
Public Function SumUpRecursive(numbers As IEnumerable(Of Integer), target As Integer, solutionLength As Integer) As IEnumerable(Of IEnumerable(Of Integer))
Return SumUpRecursive(numbers, target).Where(Function(item) item.Count() <= solutionLength)
End Function
Public Function SumUpRecursive(numbers As IEnumerable(Of Integer), target As Integer) As IEnumerable(Of IEnumerable(Of Integer))
Return SumUpRecursive(numbers, target, {}, New List(Of IEnumerable(Of Integer)))
End Function
Private Function SumUpRecursive(numbers As IEnumerable(Of Integer), target As Integer, part As IEnumerable(Of Integer), solutions As List(Of IEnumerable(Of Integer))) As IEnumerable(Of IEnumerable(Of Integer))
Dim s = part.Sum()
If s = target Then solutions.Add(part)
If s >= target Then
Return Nothing
End If
For i As Integer = 0 To numbers.Count - 1
Dim remaining = New List(Of Integer)()
Dim n As Integer = numbers(i)
For j As Integer = i + 1 To numbers.Count - 1
remaining.Add(numbers(j))
Next
Dim part_rec = New List(Of Integer)(part) From {n}
SumUpRecursive(remaining, target, part_rec, solutions)
Next
Return solutions
End Function
代码形式:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim low = 1, high = 80
Dim numbers = Enumerable.Range(low, high - low + 1)
Dim target = 15
Dim nums = SumUpRecursive(numbers, target)
If nums Is Nothing Then
MsgBox("Failure :(")
Else
TxtListScanTxt.Lines = nums.Select(Function(b) String.Join(", ", b)).ToArray()
End If
End Sub
还要注意,某些代码已得到简化,例如自动整数列表
Dim low = 1, high = 80
Dim numbers = Enumerable.Range(low, high - low + 1)
(如果您想排除一些数字,可以这样操作(很抱歉,我没有打扰您实际上是否从1到80的所有数字都在那里)):
Enumerable.Range(low, high - low + 1).Except({1, 2, 3, 5, 8, 13, 21, 34, 55})
因此,一旦您有重载,就没有理由调用大型递归函数,传递新列表了,这对于使用您的代码的其他人(您的教授?)来说确实令人困惑。您可以使用访问修饰符将其隐藏起来,然后简单地调用一个更简单的重载。
尽可能将类型更改为IEnumerable
,而不是List
。
但是将解决方案限制为最大数量的关键在于第一次过载,
SumUpRecursive(numbers, target).Where(Function(item) item.Count() <= solutionLength)
当然,如果您想限制为单个数量,可以这样做
SumUpRecursive(numbers, target).Where(Function(item) item.Count() = solutionLength)
,如果愿意,可以将其放在单独的重载中。最小/最大范围也可以。
我希望其中一些有用。