如何判断两个数组是否共享相同的元素?

时间:2021-10-03 10:03:57

So this is a simpler form of my problem. Lets say I have 2 arrays. A= {1,2} and B={2,4,6}. If A and B share an element then delete that element from B. I know you can loop through and compare each element in A to each element in B, but there's got to be a better way!

这是一个更简单的形式。假设有两个数组。一个= { 1,2 }和B = { 2 4 6 }。如果A和B共享一个元素,那么从B中删除这个元素,我知道你可以对A中的每个元素和B中的每个元素进行循环和比较,但是一定有更好的方法!

4 个解决方案

#1


4  

If your arrays are sorted (or you can sort the arrays), you can then work through both arrays simultaneously. Starting at the beginning of both arrays and going until you would advance one of the pointers beyond the end of its respective array:

如果数组已排序(或者可以对数组进行排序),则可以同时处理两个数组。从两个数组的开头开始,直到将其中一个指针向前移动到其各自数组的末尾:

  • If a < b then advance the a pointer
  • 如果a < b,则推进a指针
  • If a = b then delete the element at b
  • 如果a = b,则删除b处的元素
  • If a > b then advance the b pointer
  • 如果是>b,则向前推进b指针

#2


2  

You have to write code, but it doesn't have to be a brute-force doubly nested loop and you don't have to do any messy removal of individual elements from arrays.

您必须编写代码,但它不必是一个蛮力双嵌套循环,也不必从数组中任意删除单个元素。

If you add a reference to the Microsoft Scripting Runtime (from the Tools menu in the VBE), you can use a Dictionary object to make this easier. It has methods for 'Exists', 'Remove', and 'Keys'. So you could loop through B and add the elements as keys in the Dictionary, and then loop through A, checking to see if those elements exist, and if so, removing them.

如果您向Microsoft脚本运行时(来自VBE中的Tools菜单)添加引用,您可以使用Dictionary对象来简化这一过程。它有“存在”、“删除”和“键”的方法。你可以在B中循环,将元素作为键添加到字典中,然后在A中循环,检查这些元素是否存在,如果存在,删除它们。

As pseudocode:

伪代码:

for each elem in b
    dict(elem)=0 
next elem

for each elem in a
    if dict.exists(elem)
        dict.remove(elem)
    end if
next elem

return dict.keys

The above approach also removes duplicates from B if there are any.

上面的方法还可以从B中删除副本(如果有的话)。

If you know your arrays don't have error values as elements, you can also use MATCH (and in VBA 'Application.Match' or 'Application.WorksheetFunction.Match'). Doing something like

如果知道数组作为元素没有错误值,也可以使用MATCH(在VBA的应用程序中)。匹配”或“Application.WorksheetFunction.Match”)。做这样的事

=MATCH({2,4,6},{1,2},0)

will return {2,#N/A,#N/A}. Any position with #N/A is the position of an element of B that wasn't in A. If you do the match in the worksheet, you can then drag a formula like

将返回{ 2 # N / N / A号}。任何带有#N/A的位置都是不属于A的B元素的位置

=IF(ISNA(cell of match),corresponding cell of B,NA())

and then filter out the #N/As from that. In VBA, you could do (more pseudocode):

然后过滤掉#N/。在VBA中,你可以做(更多的伪代码):

matches=application.match(b,a,0) 

for each elem in matches
    if iserror(elem)
        add corresponding element of b to result
    end
next elem

redim result to new smaller size

return result

Of course, then you have to worry about array starting bounds, etc.

当然,你需要考虑数组的起始边界等等。

#3


0  

No there is not I think. You have to loop through.

不,我想没有。你必须循环。

#4


0  

If values inside a array are unique for its array, you could make the array indexes the actual values, allowing you to seek directly to its index, instead of scanning the entire array.

如果数组中的值对其数组是唯一的,那么可以将数组索引作为实际值,从而允许您直接查找其索引,而不是扫描整个数组。

Start with the array that has fewer elements, and i assume you are wanting to do excel/VB? I made a picture to illustrate the idea.

从元素较少的数组开始,我假设您想要使用excel/VB?我画了一张图来说明这个想法。

http://img694.imageshack.us/img694/1503/hackmap.jpg

http://img694.imageshack.us/img694/1503/hackmap.jpg

Instead of having two nested loops, you have one loop, and it only iterates as many times as the smallest array.

不是有两个嵌套的循环,而是有一个循环,它的迭代次数只相当于最小数组的迭代次数。

#1


4  

If your arrays are sorted (or you can sort the arrays), you can then work through both arrays simultaneously. Starting at the beginning of both arrays and going until you would advance one of the pointers beyond the end of its respective array:

如果数组已排序(或者可以对数组进行排序),则可以同时处理两个数组。从两个数组的开头开始,直到将其中一个指针向前移动到其各自数组的末尾:

  • If a < b then advance the a pointer
  • 如果a < b,则推进a指针
  • If a = b then delete the element at b
  • 如果a = b,则删除b处的元素
  • If a > b then advance the b pointer
  • 如果是>b,则向前推进b指针

#2


2  

You have to write code, but it doesn't have to be a brute-force doubly nested loop and you don't have to do any messy removal of individual elements from arrays.

您必须编写代码,但它不必是一个蛮力双嵌套循环,也不必从数组中任意删除单个元素。

If you add a reference to the Microsoft Scripting Runtime (from the Tools menu in the VBE), you can use a Dictionary object to make this easier. It has methods for 'Exists', 'Remove', and 'Keys'. So you could loop through B and add the elements as keys in the Dictionary, and then loop through A, checking to see if those elements exist, and if so, removing them.

如果您向Microsoft脚本运行时(来自VBE中的Tools菜单)添加引用,您可以使用Dictionary对象来简化这一过程。它有“存在”、“删除”和“键”的方法。你可以在B中循环,将元素作为键添加到字典中,然后在A中循环,检查这些元素是否存在,如果存在,删除它们。

As pseudocode:

伪代码:

for each elem in b
    dict(elem)=0 
next elem

for each elem in a
    if dict.exists(elem)
        dict.remove(elem)
    end if
next elem

return dict.keys

The above approach also removes duplicates from B if there are any.

上面的方法还可以从B中删除副本(如果有的话)。

If you know your arrays don't have error values as elements, you can also use MATCH (and in VBA 'Application.Match' or 'Application.WorksheetFunction.Match'). Doing something like

如果知道数组作为元素没有错误值,也可以使用MATCH(在VBA的应用程序中)。匹配”或“Application.WorksheetFunction.Match”)。做这样的事

=MATCH({2,4,6},{1,2},0)

will return {2,#N/A,#N/A}. Any position with #N/A is the position of an element of B that wasn't in A. If you do the match in the worksheet, you can then drag a formula like

将返回{ 2 # N / N / A号}。任何带有#N/A的位置都是不属于A的B元素的位置

=IF(ISNA(cell of match),corresponding cell of B,NA())

and then filter out the #N/As from that. In VBA, you could do (more pseudocode):

然后过滤掉#N/。在VBA中,你可以做(更多的伪代码):

matches=application.match(b,a,0) 

for each elem in matches
    if iserror(elem)
        add corresponding element of b to result
    end
next elem

redim result to new smaller size

return result

Of course, then you have to worry about array starting bounds, etc.

当然,你需要考虑数组的起始边界等等。

#3


0  

No there is not I think. You have to loop through.

不,我想没有。你必须循环。

#4


0  

If values inside a array are unique for its array, you could make the array indexes the actual values, allowing you to seek directly to its index, instead of scanning the entire array.

如果数组中的值对其数组是唯一的,那么可以将数组索引作为实际值,从而允许您直接查找其索引,而不是扫描整个数组。

Start with the array that has fewer elements, and i assume you are wanting to do excel/VB? I made a picture to illustrate the idea.

从元素较少的数组开始,我假设您想要使用excel/VB?我画了一张图来说明这个想法。

http://img694.imageshack.us/img694/1503/hackmap.jpg

http://img694.imageshack.us/img694/1503/hackmap.jpg

Instead of having two nested loops, you have one loop, and it only iterates as many times as the smallest array.

不是有两个嵌套的循环,而是有一个循环,它的迭代次数只相当于最小数组的迭代次数。