假设我有一组数字for (int i = 0; i < 10; i++){
array[i] = array[i] - '0';
}
,这些数字会给我(澄清)numbers = [70, 68, 45, 55, 47, 50, 69]
。
我希望找到指定45, 47, 50, 55, 68, 69, 70
内的最大数字组,具体取决于我正在处理的数据集。让我们说,为了论证,我想找到彼此在3之内的所有数字。
所以,通过上面的输入,我的程序的输出将是:range
,因为这是最大的数字组。如果我有多个相等的列表,我选择具有最高数字的列表。
我已经写了一个程序来解决我想要实现的目标(或者似乎,因为我无法正常看到我的程序的例外):我要求你的是:
...帮助我改进算法的这一部分的数学概念。我觉得我只是在做一些有效的事情,但这真的,非常不是最佳的和,这看起来并不好看。我不是在寻找最优的算法,但我希望以更简单,更有说服力的方式完成这项任务。 :)
证明我完成了工作:
[70, 68, 69]
答案 0 :(得分:1)
Python 3,但我认为你需要做的就是让它适用于python 2是从print语句中删除括号。
# uderscore for the _range input so we don't override the builtin range() function
def find_matching_numbers(numbers, _range=3):
numbers = sorted(numbers)
# sorting first allows us a faster algorithm because we know the range
# is our current number - first in the list
lists = []
for num in numbers:
lists.append([num])
# don't look at the last list because we just added this number
for l in lists[:-1]:
if num - l[0] <= _range:
l.append(num)
# timsort is stable, so the "largest" list will be last
return sorted(lists, key=len)[-1]
numbers = [70, 68, 45, 55, 47, 50, 69]
print(find_matching_numbers(numbers))
# [68, 69, 70]
visited = set()
for i in range(1, max(numbers) - min(numbers) + 1):
n = find_matching_numbers(numbers, i)
if sum(n) not in visited:
visited.add(sum(n))
print(i, n)
# 1 [69, 70]
# 2 [68, 69, 70]
# 10 [45, 47, 50, 55]
# 15 [55, 68, 69, 70]
# 20 [50, 55, 68, 69, 70]
# 23 [47, 50, 55, 68, 69, 70]
# 25 [45, 47, 50, 55, 68, 69, 70]
可选择剔除列表。除非大多数列表不适合剔除,否则这通常会提高性能。
def find_matching_numbers2(numbers, _range=3):
numbers = sorted(numbers) # allows us a faster algorithm
lists = []
longest = (0, 1)
for num in numbers:
remove = set()
lists.append([num])
# don't look at the last list because we just added this number
for l in lists[:-1]:
ll = len(l)
if ll > longest[1]:
longest = (num, ll)
if num - l[0] <= _range:
l.append(num)
elif ll < longest[1]:
remove.add(l[0])
lists = [l for l in lists if l[0] not in remove]
# timsort is stable, so the "largest" list will be last
return sorted(lists, key=len)[-1]