2

我有两个数组,我试图在多个级别上进行比较。两者具有相同的结构,具有 3" 列。

第一列包含多边形的 ID,第二列包含区域类型,第三列包含多边形的每种区域类型的百分比。

因此,对于许多行,它会比较,例如,ID:1 类型:aaa %:100 但是对于某些元素,我有很多行具有相同的 ID。例如,我将有 ID 2,类型 aaa,25% --- ID 2,类型 bbb,25% --- ID 2,类型 ccc,50%。在第二个数组中,我将有 ID 2,类型 aaa,25% --- ID 2,类型 bbb,10% --- ID 2,类型 eee,38% --- ID 2,类型 fff,27 %。

这是一个视觉示例.. 打印屏幕

所以,我的函数必须比较这两个数组,如果有差异,给我发一封电子邮件。(我不会向你展示真正的代码,因为有 811 行)。第一个“如果”条件是

if array1.id = array2.id Then
if array1.type = array2.type Then
if array1.percent = array2.percent Then
zone_verification = True
Else
zone_verification = False

问题是因为每个数组中有超过 50 000 行。因此,当我运行该函数时,对于每个“array1.id”,该函数在 array2 中搜索 50 000 行。50 000 次搜索 50 000 行.. 运行时间相当长!

我正在寻找让它运行得更快的东西。我怎样才能让我的搜索更具体。示例:我在 array1 中有很多 id "2"。如果array2中有许多id“2”,找到它,并将所有array2.id = 3推入“子数组”或类似的东西,并在这些特定行中搜索。所以我将在array1中只有X行与array 2中的X行进行比较,而不是50 000。当array1中的每个“id 2”完成时,对“id 4”做同样的事情......和“编号 5"...

希望很清楚。这几乎是我第一次使用 VB.net,而且我有这么大的功能可以运行。

谢谢

编辑

这就是我想做的。

我在地理空间数据库中有两个不同的层。两层具有相同的结构。它们是地块 (55 000) 和土地利用层的“空间连接”。第一层是当前层,第二层是我们将在 2015 年之后使用的下一层。

所以我有,对于每个“地块”,每个土地使用的百分比。因此,对于“地块”(ID 7580-80-2532),我可以拥有 50% 的农业使用(TYPE FAR-23)和 50% 的住宅使用(RES-112)。在第一个数组中,我'将有 2 行具有相同 ID (7580-80-2532),但每行将具有不同的类型 (FAR-23, RES-112) 和不同的 %。在第二层中,相同的市政分区 (土地用途) 发生了变化。因此,相同的“地块”现在将占住宅用途 (RES-112) 的 40%、商业用途 (COM-54) 的 20% 和新农业用途 (FAR-33) 的 40%。所以,我想知道是否有一些差异。有些地块会完全一样。有些地块会保持相同的土地利用,但每个地块的百分比不一样。但是对于某些地块,土地利用会或多或少每种类型的百分比不同。

我希望此脚本比较这两个图层,并在同一地块 ID 的这两个图层之间存在差异时向我发送电子邮件。

该脚本已经在运行,但它需要太多时间。

问题是,我认为,脚本遍历数组 1 中每一行的所有数组 2。

我想要的是当array1中有超过1行具有相同的ID时,在两个数组中只取这个ID。

也许如果我按 ID 对它们进行排序,我可以写一个条件。有点像“当你找到你正在寻找的东西时,当你找到不同的价值时停止搜索?

很难解释清楚,因为我从上周开始就一直在使用 VB。而且英语不是我的第一语言!;)

4

3 回答 3

0

我根据您写的第一部分(即没有编辑部分)回答这个问题。正确的答案应该解释一个好的算法,但我建议您使用数据库功能,因为他们已经为此目的优化了许多查询。

将所有记录放在 DB 两个表中 - O(n) 时间......如果记录是静态的,则不需要每次都执行此步骤。表1 id类型百分比

表2 id类型百分比

然后使用数据库查询,像这样 select count(*) from table1 t1, table2 t2 where t1.id!=t2.id and t1.type!=t2.type (你可以使用一些更好的查询,我是什么试图说是将控制权交给 DB 以执行此操作)在您的代码中检索结果并执行必要的操作。

编辑 1) 您可以根据 ID + type + Percent 在 O(n logn) 时间内对它们进行排序,然后执行二进制搜索。2)使用适当的键将第一条记录存储在哈希映射中 - 可以是仅 ID 或 ID+类型,这将花费 O(n) 时间,如果键正确,则搜索将花费恒定时间。

于 2012-05-07T19:53:40.950 回答
0

如果您只想了解第一个和第二个数组之间是否有任何差异,您可以这样做:

Dim diff = New HashSet(of Polygon)(array1)
diff.SymmetricExceptWith(array2)

diff 将包含任何对 array1 或 array2 唯一的多边形。如果您想做其他类型的比较,也许您应该准确地解释您要做什么。

更新:

您可以像这样使用分组和查找:

'Create lookup with first array, for fast access by ID
Dim lookupByID = array1.ToLookup(Function(p) p.id)

'Loop through each group of items with same ID in array2
For Each secondArrayValues in array2.GroupBy(Function(p) p.id)

    Dim currentID As Integer = secondArrayValues.Key 'Current ID is the grouping key

    'Retrieve values with same ID in array1
    'Use a hashset to easily compare for equality
    Dim firstArrayValues As New HashSet(of Polygon)(lookupByID(currentID))

    'Check for differences between the two sets of data, for this ID
    If Not firstArrayValues.SetEquals(secondArrayValues) Then

        'Data has changed, do something
        Console.WriteLine("Differences for ID " & currentID)
    End If
Next
于 2012-05-07T16:10:34.200 回答
0

您需要定义一个结构来存储这些数据。我们将所有数据存储在一个LandParcel类中,该类将有一个HashSet<ParcelData>

public class ParcelData
{
    public ParcelType Type { get; set; } // This can be an enum, string, etc.
    public int Percent { get; set; }

    // Redefine Equals and GetHashCode conveniently
}

public class LandParcel
{
    public ID Id { get; set; } // Whatever the type of the ID is...
    public HashSet<ParcelData> Data { get; set; }
}

现在你必须建立你的数据结构,像这样:

Dictionary<ID, LandParcel> data1 = new ....

foreach (var item in array1)
{
    LandParcel p;

    if (!data1.TryGetValue(item.id, out p)
        data1[item.id] = p = new LandParcel(id);

    // Can this data be repeated?
    p.Data.Add(new ParcelData(item.type, item.percent)); 
}

data2对第二个数组的字典执行相同的操作。现在您迭代所有项目data1并将它们与具有相同 id 的项目进行比较data2

foreach (var parcel2 in data2.Values)
{
     var parcel1 = data1[parcel2.ID]; // Beware with exceptions here !!!

     if (!parcel1.Data.SetEquals(parcel2.Data))
         // You have different parcels
} 

(现在我看了一下,我们实际上是在这里做一个小型数据库查询,有点臭代码......)

对不起 C# 代码,因为我对 VB 感觉不太舒服,但它应该相当简单。

于 2012-05-07T15:54:27.183 回答