我有一对对象列表。对象可以按任意顺序出现在对中。什么是最有效的算法(和实现?)来找到相同对象之间的所有包(即允许重复的集合)。出于我的目的,可以假定对象引用是指针,或名称或一些类似的方便,简短,有用的表示。单个对是可识别的。在该对的两个部分中没有对具有相同的对象。
所以给出一对对列表(Oid是一个对象引用; Pid一对引用)
O1-P1-O2
O3-P2-O4
O5-P3-O1
O1-P4-O2
O2-P5-O1
O1-P6-O5
O7-P7-O8
应该返回:
P1;P4;P5 and P3;P6
答案 0 :(得分:5)
花哨的术语可能会使这个问题看起来很难,但实际上很简单。
pair.first <= pair.second
)pair1 < pair2
表示pair1.first < pair2.first
或pair1.first == pair2.first && pair1.second < pair2.second
。示例中的排序列表将如下所示
O1-P1-O2
O1-P4-O2
O1-P5-O2
O1-P3-O5
O1-P6-O5
O3-P2-O4
O7-P7-O8
现在,来自一个'bag'的所有元素将占据列表中的连续位置。来吧抓住它们。
也可以通过哈希来解决这个问题。
答案 1 :(得分:3)
对象上是否“小于”? 如果是这样,那么你只需通过你的对子列表就可以做到这一点。
1)创建一个空的行李集合,由两个“对象”参数索引。按照惯例,第一个索引参数应小于第二个索引参数。
2)循环浏览列表,并在min(pair.left,pair.right),max(pair.left,pair.right)找到合适的行李索引。将元素添加到该包中。
答案 2 :(得分:1)
#!/usr/bin/env python
from itertools import groupby
pairs = """
O1-P1-O2
O3-P2-O4
O5-P3-O1
O1-P4-O2
O2-P5-O1
O1-P6-O5
O7-P7-O8
""".split()
def lex_order(pair):
"""'O2-P5-O1' -> ['01', '02']"""
return sorted(pair.split('-')[::2])
data = sorted(pairs, key=lex_order)
for key, group in groupby(data, key=lex_order):
print "key=%(key)s, pairs=%(pairs)s" % dict(key=key, pairs=list(group))
输出:
key=['O1', 'O2'], pairs=['O1-P1-O2', 'O1-P4-O2', 'O2-P5-O1']
key=['O1', 'O5'], pairs=['O5-P3-O1', 'O1-P6-O5']
key=['O3', 'O4'], pairs=['O3-P2-O4']
key=['O7', 'O8'], pairs=['O7-P7-O8']
Python中的#!/usr/bin/env python
from collections import defaultdict
pairs = """
O1-P1-O2
O3-P2-O4
O5-P3-O1
O1-P4-O2
O2-P5-O1
O1-P6-O5
O7-P7-O8
""".split()
bags = defaultdict(list)
for pair in pairs:
i, _, j = pair.split('-') # 'O2-P5-O1' -> ['02', 'P5', '01']
bags[min(i,j), max(i,j)].append(pair)
import pprint;
pprint.pprint(dict(bags))
输出:
{('O1', 'O2'): ['O1-P1-O2', 'O1-P4-O2', 'O2-P5-O1'],
('O1', 'O5'): ['O5-P3-O1', 'O1-P6-O5'],
('O3', 'O4'): ['O3-P2-O4'],
('O7', 'O8'): ['O7-P7-O8']}