【问题标题】:Is it possible to divide a Array in VBA是否可以在VBA中划分数组
【发布时间】:2013-08-24 03:06:16
【问题描述】:

数组可以分割吗?

例子:

array(2) As String
array(1) = "test1"
array(2) = "test2"

~ Now Split

array1 (contains test1) & array 2 (contains test2)

我想实现二进制搜索

【问题讨论】:

  • 你必须编写一个方法来做到这一点。

标签: arrays vba search binary split


【解决方案1】:

你可以这样拆分

Sub split_array()

Dim array1(1 To 2) As String
Dim array2(1 To 2) As String
Dim array3(1 To 2) As String

array1(1) = "Test1"
array1(2) = "Test2"

array2(1) = array1(1)
array3(1) = array1(2)

End Sub

但我怀疑这不是最好的方法。我认为使用 3 个(可能是长整数)变量来表示数组中的位置会做得更好。 1代表第一个元素,1代表最后一个元素,1代表中间元素。

Dim lLowerSearchElement As Long
Dim lUpperSearchElement As Long
Dim lMiddleSearchElement As Long
Dim array1(1 to 999) as string

lLowerSearchElement = 1
lUpperSearchElement = 999
lMiddleSearchElement = (lUpperSearchElement + lLowerSearchElement) / 2

然后,您可以检查元素是否等于、大于或小于中间元素并相应地继续。

还请记住,在尝试使用二进制搜索之前,您需要对数据进行排序,如果您了解递归调用,这将很有用。

您还需要严格测试您的实现,因为一个小错误可能会导致搜索无法正常工作。

22/08/13 编辑

我用于二分搜索的实现如下:

Function bCheckSamplePoint(ByRef lSamplePointArray() As String, ByRef bfound As Boolean, _
    ByVal lSamplePoint As String) As Boolean
    'byref used for the array as could be slow to keep copying the array, bFound is used by calling procedure

    Dim lLowerSearchElement As Long
    Dim lUpperSearchElement As Long
    Dim lMiddleSearchElement As Long

    bfound = False 'False until found

    'Set initial limits of the search
    lLowerSearchElement = 0
    lUpperSearchElement = UBound(lSamplePointArray())

    Do While lLowerSearchElement <= lUpperSearchElement And bfound = False
        lMiddleSearchElement = (lUpperSearchElement + lLowerSearchElement) / 2
        If StrComp(lSamplePointArray(lMiddleSearchElement), lSamplePoint, vbTextCompare) = -1 Then
'            'Must be greater than middle element
            lLowerSearchElement = lMiddleSearchElement + 1
        ElseIf (lSamplePointArray(lMiddleSearchElement) = lSamplePoint) Then
            bfound = True
        Else
            'must be lower than middle element
            lUpperSearchElement = lMiddleSearchElement - 1
        End If 'lSamplePointArray(lmiddlesearchlelemnt) < lSamplePoint

    Loop 'While lLowerSearchElement <= lUpperSearchElement

ErrorExit:
    bCheckSamplePoint = bReturn
    Exit Function

正如您所见,这种二分搜索只是检查是否在字符串数组中找到了一个字符串,但它可以被修改用于其他目的。

【讨论】:

  • 一般我是用Java写代码的,内存中直接有split函数。正如我理解你的答案,我应该使用循环来复制数组。但在我看来,这不是一种节省时间的方法。您将失去二进制搜索背后的一般想法。还是我误会了你?
  • 我的回答背后的想法是,您实际上并没有对数组做任何事情,而是更改了指向数组中位置的长整数的值,因此使用 1000 元素数组的示例如果您要查找的值小于您将上部搜索元素设置为中间元素 -1 并重新开始的中间搜索元素。我将编辑我的文本以向您展示我使用的实现。
【解决方案2】:

您不需要拆分函数来进行二分搜索

我的 VBA 版本的二分搜索可以在
http://fastexcel.wordpress.com/2011/08/02/developing-faster-lookups-part-3-a-binary-search-udf/ 找到

【讨论】:

  • 你能解释一下,为什么 LookupArray 是二维的?
  • 因为如果你从一个范围内获取值到一个变量中,结果是一个二维数组,即使这个范围是单列。
【解决方案3】:

将数组拆分成块

Public Function splitArray(ByVal initial_array As Variant, Optional chunk_size As Long = 1) As Variant()
  Dim split_array() As Variant
  Dim chunk() As Variant
  Dim chunk_index As Integer: chunk_index = 0
  Dim array_index As Integer: array_index = 1

  If UBound(initial_array) > chunk_size Then
    For i = 0 To UBound(initial_array)
      If (i + 1) / (chunk_size * array_index) = 1 Or i = UBound(initial_array) Then
        ReDim Preserve chunk(chunk_index)
        chunk(chunk_index) = initial_array(i)
        ReDim Preserve split_array(array_index - 1)
        split_array(array_index - 1) = chunk
        chunk_index = 0
        array_index = array_index + 1
      Else
        ReDim Preserve chunk(chunk_index)
        chunk(chunk_index) = initial_array(i)
        chunk_index = chunk_index + 1
      End If
    Next i
    splitArray = split_array
  Else
    ReDim Preserve split_array(0)
    split_array(0) = initial_array
    splitArray = split_array
  End If

End Function

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-14
    • 1970-01-01
    • 1970-01-01
    • 2011-09-22
    • 1970-01-01
    • 2019-06-28
    • 1970-01-01
    相关资源
    最近更新 更多