在VBA中实现反转列表?

在VBA中实现反转列表?,vba,data-structures,Vba,Data Structures,如何在VBA中以灵活高效的方式实现一组(正)整数?特别是,使用哪种底层数据结构 它将用于表示一组正整数 函数将用于将A到B范围内的整数添加到集合中。函数将返回从A到B的一组整数,这些整数没有被添加,因为它们已经在集合中。换句话说,函数将返回旧集合(在调用函数之前)与给定范围内整数集合的交集 另一个函数将返回整数A是否在集合中(布尔值)。对于数据结构,您只需使用数组(整数或双精度或其他)。在VBA中,最简单的方法是使用变量将数组传递给函数。如果要添加O(1),可以使用ArrayList(不是本机V

如何在VBA中以灵活高效的方式实现一组(正)整数?特别是,使用哪种底层数据结构

它将用于表示一组正整数

函数将用于将A到B范围内的整数添加到集合中。函数将返回从A到B的一组整数,这些整数没有被添加,因为它们已经在集合中。换句话说,函数将返回旧集合(在调用函数之前)与给定范围内整数集合的交集


另一个函数将返回整数A是否在集合中(布尔值)。

对于数据结构,您只需使用数组(整数或双精度或其他)。在VBA中,最简单的方法是使用变量将数组传递给函数。如果要添加
O(1)
,可以使用
ArrayList
(不是本机VBA,但可以在VBA中使用)以下是一个数组实现的搜索函数:

Function InRanges(A As Variant, item As Variant) As Boolean

    Dim lower As Long, mid As Long, upper As Long
    lower = LBound(A)
    upper = UBound(A)

    If item < A(lower) Or item >= A(upper) Then
        InRanges = False
    Else 'A(lower) =< item < A(upper)
        Do Until upper = lower + 1
            mid = Int((lower + upper) / 2)
            If A(mid) = item Then
                'return result of a check if this occurs at an even or odd location
                InRanges = ((mid - LBound(A)) Mod 2 = 0)
                Exit Function
            ElseIf item < A(mid) Then
                upper = mid
            Else 'A(mid) < item
                lower = mid
            End If
        Loop
        InRanges = ((lower - LBound(A)) Mod 2 = 0)
    End If
End Function
输出:

9: False
10: True
11: True
12: True
13: True
14: True
15: False
16: False
17: False
18: False
19: False
20: False
21: False
22: False
23: False
24: False
25: True
26: True
27: True
28: True
29: True
30: True
31: True
32: True
33: True
34: True
35: True
36: True
37: True
38: False
39: False

对于数据结构,您只需要使用一个数组(由整数或双精度或其他内容组成)。在VBA中,最简单的方法是使用变量将数组传递给函数。如果要添加
O(1)
,可以使用
ArrayList
(不是本机VBA,但可以在VBA中使用)以下是一个数组实现的搜索函数:

Function InRanges(A As Variant, item As Variant) As Boolean

    Dim lower As Long, mid As Long, upper As Long
    lower = LBound(A)
    upper = UBound(A)

    If item < A(lower) Or item >= A(upper) Then
        InRanges = False
    Else 'A(lower) =< item < A(upper)
        Do Until upper = lower + 1
            mid = Int((lower + upper) / 2)
            If A(mid) = item Then
                'return result of a check if this occurs at an even or odd location
                InRanges = ((mid - LBound(A)) Mod 2 = 0)
                Exit Function
            ElseIf item < A(mid) Then
                upper = mid
            Else 'A(mid) < item
                lower = mid
            End If
        Loop
        InRanges = ((lower - LBound(A)) Mod 2 = 0)
    End If
End Function
输出:

9: False
10: True
11: True
12: True
13: True
14: True
15: False
16: False
17: False
18: False
19: False
20: False
21: False
22: False
23: False
24: False
25: True
26: True
27: True
28: True
29: True
30: True
31: True
32: True
33: True
34: True
35: True
36: True
37: True
38: False
39: False

谢谢,我现在有了一个使用阵列的实现,每当范围的数量发生变化时,都会对其进行重拨。函数可以向集合中添加一个正整数范围,并返回上一个集合与添加的范围之间的重叠集合。函数返回给定整数是否在集合中。函数返回集合的补码。函数返回集合的文本表示形式,并使用可选参数传递要在范围之前、内部和之后使用的符号。测试套件对集合执行操作,并在每个集合之间检查结果。代码太长,无法发布。我很高兴您能使用它
ReDim Preserve
可能会很昂贵(它会将保留的数据复制到新数组中),因此如果您经常这样做,并且不介意使用纯VBA,那么您可能需要了解如何从VBA使用它们。在我写下我的答案后,我注意到数组列表甚至有一个二进制搜索方法,因此您应该能够相当容易地对成员资格检查进行编码。谢谢,我现在有了一个使用数组的实现,每当范围数发生变化时,都会重新对其进行编码。函数可以向集合中添加一个正整数范围,并返回上一个集合与添加的范围之间的重叠集合。函数返回给定整数是否在集合中。函数返回集合的补码。函数返回集合的文本表示形式,并使用可选参数传递要在范围之前、内部和之后使用的符号。测试套件对集合执行操作,并在每个集合之间检查结果。代码太长,无法发布。我很高兴您能使用它
ReDim Preserve
可能会很昂贵(它会将保留的数据复制到新数组中),因此如果您经常这样做,并且不介意使用纯VBA,那么您可能需要了解如何从VBA使用它们。在我写下我的答案后,我注意到数组列表甚至有一个二进制搜索方法,因此您应该能够相当容易地编写成员资格检查代码。