Python k序列表的交集

Python k序列表的交集,python,list,set,intersection,set-intersection,Python,List,Set,Intersection,Set Intersection,我正在学习python,并尝试使用SvS算法(小对小)与k集(有序列表)相交。我的程序成功了,但我必须运行函数数次,直到它到达交叉点。如果你能暗示我做错了,我将不胜感激 def SvS_BS(Set_list): Set_list = sorted(Set_list) candidato = Set_list[0] answer_set = [] for S in Set_list: lS=0 for S in Set_list:

我正在学习python,并尝试使用SvS算法(小对小)与k集(有序列表)相交。我的程序成功了,但我必须运行函数数次,直到它到达交叉点。如果你能暗示我做错了,我将不胜感激

def SvS_BS(Set_list):
    Set_list = sorted(Set_list)
    candidato = Set_list[0]
    answer_set = []
    for S in Set_list:
        lS=0
        for S in Set_list:
            for e in candidato:
                b = BusquedaBinaria(S,0,len(S)-1,e)
                if b == -1:
                    candidato.remove(e)
                else: 
                    lS += b                
    return candidato
注意:BusquedaBinaria是二进制搜索(是从已排序的项目列表中查找项目的一种有效算法。它的工作原理是将可能包含该项目的列表部分重复划分为一半,直到您将可能的位置缩小为一个):

如果使用以下示例运行函数:

A=[8, 316, 456, 802, 907, 1072, 1222, 1227, 1472, 1497, 1552, 1566, 1728, 2025, 2283, 2367, 2383, 2789, 3024, 3108, 3170, 3178, 3224, 3249, 3252]
B=[8, 1222, 10862, 18559, 28129, 41980, 43513, 44066]
第一个输出是:

SvS_BS([A,B])
output: [8, 907, 1222, 1552, 2283, 3024, 3224]
我再次运行该函数并得到:

output: [8, 1222, 3224] 
最后,我再次运行它并获得输出(这是预期的结果)


我提前感谢您能帮助我在第一次执行时获得结果

我发现您的代码中有一些小错误。 首先,在Set_List中对S进行两次迭代,只是为了重置lS值(可以在1个循环中执行),但无论如何都不会使用该变量

另外,当您在Set_List中为S进行检查时,您不需要在循环中检查candidateto List本身。所以我换了

for S in range(1,len(Set_list)):
它将只在第一个集合(候选集合)之后的集合上迭代。 现在你得到了一个S中的整数,所以我把你的二进制搜索改为

b = BusquedaBinaria(Set_list[S],0,len(Set_list[S])-1,e)
现在,这应该检查候选集与除自身之外的所有其他集

最后,我认为这里的大问题是设计和技术问题。第一个技术问题:在遍历Candidateo时删除它,这是一个坏主意,会使它跳过值

因此,您需要对照所有其他集合检查第一个集合,因此我将颠倒循环的顺序,如下所示。但您还必须确保只返回所有其他列表中的值。(我认为您在未使用的lS变量中已经接近这个想法)。由于您从未实际使用从二进制搜索返回的位置,因此我成功地找到了返回a 1的位置,并将其累积到b值中。如果b值在搜索所有其他列表(减去candidateo)后添加到列表数,则它位于所有列表中,我们将其添加到答案集中。然后返回答案集

def BusquedaBinaria( lista, izq, der, x):
    if der >= izq:
        m = izq + ( der-izq ) // 2
        if lista[m] == x:
            return 1
        if lista[m] > x:
            return BusquedaBinaria(lista, izq,m - 1, x)
        return BusquedaBinaria(lista, m + 1, der, x)
    return -1

我认为这应该是可行的,我也尝试了一个额外的阵列,但没有做详尽的边缘案例测试,让我知道是否适合你

让你的问题变得独立。我们不知道BusquedaBinaria是什么。对不起,你说得对。对应于二进制搜索。我将在几秒钟内编辑这个问题,在晨光中再看一次,我只想提到,对于相对较小长度的集合列表,这应该可以很好地工作。如果您想要有任意长的集合列表,或者只是想进行一个小的优化,您可以检查BusquedaBinaria是否返回-1,如果是,则“继续”到Candidateo中的下一个e。(在if check中使用continue关键字)。删除b==comp_list_len检查,并将其附加到for循环后的答案集(即,它从未达到“continue”条件)。直觉是检查没有列表没有它,而所有列表都有。devintark。非常感谢你。你真的帮了我很多。我将考虑你的意见。我正在学习python,我对它们感到非常兴奋。再次感谢。
b = BusquedaBinaria(Set_list[S],0,len(Set_list[S])-1,e)
def BusquedaBinaria( lista, izq, der, x):
    if der >= izq:
        m = izq + ( der-izq ) // 2
        if lista[m] == x:
            return 1
        if lista[m] > x:
            return BusquedaBinaria(lista, izq,m - 1, x)
        return BusquedaBinaria(lista, m + 1, der, x)
    return -1
def SvS_BS_d(Set_list):
    Set_list = sorted(Set_list)
    comp_list_len = len(Set_list)-1
    candidato = Set_list[0]
    answer_set = []
    for e in candidato:
        b = 0
        for S in range(1, len(Set_list)):
            b += BusquedaBinaria(Set_list[S],0,len(Set_list[S])-1,e)
        if b == comp_list_len:
            answer_set.append(e)

    return answer_set