我试图在VBA中编写一个简单的冒泡排序功能,但它不起作用。代码如下:
Public Function BubbSort(arr As Variant) As Variant
Dim arrReturn As Variant
arrReturn = Array()
ReDim arrReturn(UBound(arr))
arrReturn = arr.Value
For i = 1 To UBound(arr) - 1
For j = 1 To UBound(arr) - 1
If arrReturn(j) > arrReturn(j + 1) Then
temp = arrReturn(j)
arrReturn(j) = arrReturn(j + 1)
arrReturn(j + 1) = temp
End If
Next j
Next i
arr = arrReturn
End Function
在Excel中我尝试选择4x1范围的单元格并插入公式$ = BubbSort(A1:A4)$并按Ctrl + Shift + Enter以使其作为数组函数工作,但它说"函数有错误& #34 ;.有什么帮助吗?
答案 0 :(得分:2)
如果arr
是一个范围,则UBound(arr)
会抛出错误。解决这个问题的方法是使用
arrReturn = arr.Value
而不仅仅是
arrReturn = arr
然后使用Ubound(arrReturn)
此外 - arrReturn
将是一个二维数组而不是一维数组。对arrReturn
的所有引用应如下所示: arrReturn(j,1)
最后 - 你没有返回任何东西(在VBA中分配给函数名)。
以下代码似乎有效(如果冒充排序可以被描述为"正在工作"):
Public Function BubbSort(arr As Variant) As Variant
Dim arrReturn As Variant
Dim i As Long, j As Long, temp As Variant
arrReturn = arr.Value
For i = 1 To UBound(arrReturn) - 1
For j = 1 To UBound(arrReturn) - 1
If arrReturn(j, 1) > arrReturn(j + 1, 1) Then
temp = arrReturn(j, 1)
arrReturn(j, 1) = arrReturn(j + 1, 1)
arrReturn(j + 1, 1) = temp
End If
Next j
Next i
BubbSort = arrReturn
End Function
上述内容仅在传递列中包含的范围时有效。可以使其更灵活,能够处理列范围或行范围或VBA阵列。
答案 1 :(得分:2)
虽然John Coleman的代码在技术上有效,但它存在根本缺陷。您会注意到i
上的外环是不变的 - 从不使用循环值。
Bubblesort 确实是低效的(至少对于长序列而言),但没有代码执行的那么多。
在内循环的末尾,最大的元素将传播到序列的最末端。因此,在内循环的下一次重复期间,无需将其与任何先前的元素进行比较。如果每次将内循环缩短1(总计,到目前为止的外循环完成次数Public Function Bubble1(arr As Variant) As Variant
Dim arrReturn As Variant
Dim i As Long, j As Long, temp As Variant
arrReturn = arr.Value
For i = UBound(arrReturn, 1) To 2 Step -1
For j = 1 To i - 1
If arrReturn(j, 1) > arrReturn(j + 1, 1) Then
temp = arrReturn(j, 1)
arrReturn(j, 1) = arrReturn(j + 1, 1)
arrReturn(j + 1, 1) = temp
End If
Next j
Next i
Bubble1 = arrReturn
End Function
),则将循环次数减少50%:
Public Function Bubble2(arr As Variant) As Variant
Dim arrReturn As Variant
Dim i As Long, j As Long, temp As Variant
Dim sorted As Boolean
arrReturn = arr.Value
For i = UBound(arrReturn, 1) To 2 Step -1
sorted = True
For j = 1 To i - 1
If arrReturn(j, 1) > arrReturn(j + 1, 1) Then
temp = arrReturn(j, 1)
arrReturn(j, 1) = arrReturn(j + 1, 1)
arrReturn(j + 1, 1) = temp
sorted = False
End If
Next j
If sorted Then Exit For
Next i
Bubble2 = arrReturn
End Function
虽然我们可以通过观察,如果所有元素都已排序(即内部循环中没有发生交换),我们可以进一步减少工作量 - 进一步的循环是多余的。我们可以使用标志来实现它:
> "one, two, three ".split(',').map(s => s.trim());
[ 'one', 'two', 'three' ]