检查两个bitArrays中的位是否相同的最佳方法是什么?

时间:2017-09-17 18:59:30

标签: vb.net

我经常需要比较两个位数组以查看它们是否相同,所以我找到了一个对我来说看起来不太合适的函数,看起来它可能更好,因为有三个逻辑运算在一条线上。我很想知道它是否可以简化它。

Public Overloads Shared Function AreEqual(ByVal ba1 As BitArray, ByVal ba2 As BitArray) As Boolean

    If ba1.Length <> ba2.Length Then
        Return False
    End If

    Dim i As Integer
    For i = 0 To ba1.Length - 1
        If Not (Not ba1(i)) Xor ba2(i) Then
            Return False
        End If
    Next
    Return True

End Function

修改

经过几个小时的测试和头脑风暴后,我开始考虑减少这三个逻辑运算符的数量,并将其中一个放入变量中,这意味着一次性恢复所有位而不是一点一点地恢复。这是结果,并且比前一个快得多,大约快3倍:

Public Overloads Shared Function AreEqual(ByVal ba1 As BitArray, ByVal ba2 As BitArray) As Boolean

    If ba1.Count <> ba2.Count Then
        Return False
    End If

    Dim revBa1 As BitArray = ba1.Not ' <<
    Dim i As Integer

    For i = 0 To ba1.Count - 1
        If (Not revBa1(i)) Xor ba2(i) Then ' eliminates one logical operation existing here before
            Return False
        End If
    Next
    Return True

End Function

现在,比这更快? :)谁知道,也许......

编辑2:

经过一些更多的测试和不确定的结果后,我注意到该函数的第二个版本是不正确的。虽然它得到了正确的结果,但它改变了ba1值,就像它通过函数传递给函数一样:

'------------------------
'ba1 before = 000000000000000000000000000000001
'ba2 before = 000000000000000000000000000000001
'ba1 after = 111111111111111111111111111111110
'ba2 after = 000000000000000000000000000000001
'function result = True
'------------------------

有什么想法吗?

编辑3: 解决方案很简单,但功能不再快:

Dim revBa1 As New BitArray(ba1)
    revBa1 = revBa1.Not()

编辑4: 是的,就是这样:

Public Overloads Shared Function AreEqual(ByVal ba1 As BitArray, ByVal ba2 As BitArray) As Boolean

    If ba1 Is Nothing OrElse ba2 Is Nothing Then
        Return False
    End If

    If ba1.Count <> ba2.Count Then
        Return False
    End If

    Dim i As Integer
    For i = 0 To ba1.Count - 1
        If ba1(i) Xor ba2(i) Then
            Return False
        End If
    Next
    Return True

End Function

我猜有时我们不会因为树木而看不到森林:)

1 个答案:

答案 0 :(得分:1)

class Cartesian{ public: double x() const { return r_(0); } double y() const { return r_(1); } double z() const { return r_(2); } std::vector<double> const& r() const { return r_; }; Cartesian* operator=(std::vector<double> const& r) {r_ = r;} private: std::vector<double> r_; //Eigen::Array3d r_; }; // Send vector of Cartesian void sendData(std::vector<Cartesian> const& v) { std::vector<double> data; for (auto const& i : v) { data.insert(data.end(), v.r().begin(), v.r().end()); } MPI_Send(data.begin(), data.size(), MPI_DOUBLE, 0, 1, MPI_COMM_WORLD); } // Receive vector of Cartesian std::vector<Cartesian> recvData() { int n; MPI_Status status; MPI_Probe(0, 0, MPI_COMM_WORLD, &status); // Incoming? MPI_Get_count(&status, MPI_INT, &n); // Number of incoming std::vector<Cartesian> v; if (n>0) { std::vector<double>(n); MPI_Recv(n.begin(), n, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); v.resize(n/3); int i = 0; for (auto i : v) { i.r(*b.begin()+3*i); ++i; } } return v; } int main() { MPI_Init(NULL, NULL); int size, rank; MPI_Comm_size(MPI_COMM_WORLD, &size); MPI_Comm_rank(MPI_COMM_WORLD, &rank); std::vector<Cartesian> data; if (rank == 0) { data.resize(1000); sendData(data); } else { data = recvData(); } MPI_Finalize(); } ba1(i)返回可以直接比较的布尔值:

ba2(i)

Function AreEqual(ba1 As BitArray, ba2 As BitArray) As Boolean If ba1.Count <> ba2.Count Then Return False For i = 0 To ba1.Count - 1 If ba1(i) <> ba2(i) Then Return False Next Return True End Function 使用Integer array to store the bits,因此对于更大的BitArray(可能大约100位?你可能需要测试它),在比较之前将它们复制到整数数组可能会快一点:

BitArray

作为旁注,比较可枚举集合的越来越慢的方法是SequenceEquals

Function AreEqual(ba1 As BitArray, ba2 As BitArray) As Boolean

    If ba1.Count <> ba2.Count Then Return False

    If ba1.Count < 64 Then                    ' needs some testing to determine this number
        For i = 0 To ba1.Count - 1
            If ba1(i) <> ba2(i) Then Return False
        Next
    Else
        Dim a1 = New Integer((ba1.Length - 1) \ 32) {}
        Dim a2 = New Integer((ba2.Length - 1) \ 32) {}

        ba1.CopyTo(a1, 0)
        ba2.CopyTo(a2, 0)

        For i = 0 To a1.Length - 1
            If a1(i) <> a2(i) Then Return False
        Next
    End If

    Return True
End Function