我有一个最喜欢的电影列表,我想根据我的喜好从最好的电影(最多点)到最糟糕的电影(只有1分)进行排序。
让我们说这个列表已包含300个已分类的电影,您想要确定新电影的分数。您可以将新电影与排序列表中的每部电影进行比较,也可以利用列表排序的知识。
我尝试将其实现为二进制搜索,因此每个插件(新电影)都具有对数复杂度。 二进制搜索实现对我来说很容易:
def binSearch(lst, number):
left = 0
right = len(lst) - 1
while left <= right:
middle = left + ((right - left) / 2)
if number == lst[middle]:
return True
else:
if number < lst[middle]:
right = middle - 1
else:
left = middle + 1
return False
但确定点对我来说非常困难。我已经调试了几个小时,但仍然会出现一些错误。我多次更改了实现,但没有任何帮助。 这是我的最后一个解决方案(也许算法处于更糟糕的状态,然后是在开始时)
def determinePoints(lst, new):
# lst is a list of tuples with movies
# new is a tuple with new movie (has no point associated yet)
if not lst: # no movie has points so far
return 1 # now exists only one movie with associated points
newTitle = new[0]
newGenre = new[1]
atMost = len(lst)
atLeast = 0
while atLeast < atMost - 1: # algorithm doesn't work
# if only two movies have associated points
center = twoPointsCenter(atLeast, atMost)
(title, genre) = lst[center]
os.system("clear")
competitionStrings = [ newTitle, newGenre, "\n" * 10, title, genre ]
print "\n".join([ x.center(150) for x in competitionStrings ])
c = getch()
if c == "j": # new movie is worse than this
atMost = center - 1
if atMost <= 1:
return 1
else: # new movie is better than this
atLeast = center + 1
if atLeast >= len(lst):
return max(atLeast, 1)
return max(twoPointsCenter(atLeast, atMost), 1)
def twoPointsCenter(left, right):
return left + ((right - left) / 2)
你能否纠正我的解决方案(或更好地实施)以收敛并以正确的结果结束?
它应该使用0,1,2,......等长度的lst。它不应该返回小于1的值。在电影列表中不应该有两个具有相同点数的电影
当函数determinePoints
返回点数时,我将为此电影更新数据库,并为每部电影增加1,其中&gt; =点数比此新电影更多。
谢谢
答案 0 :(得分:1)
我认为您需要更好地查看边界索引。 len(lst)
比最大索引大一个,例如:列表从0开始。我冒昧地使用0作为最低分数;这将直接为您提供lst.insert
的位置。此外,我无法抗拒,并使其更像PEP 8。
你不需要所有的角落案件;我认为他们工作正常。
def determine_points(lst, new):
# lst is a list of tuples with movies, ranked by how good the movie is
# new is a tuple with new movie
# the new movies position is to be determined
new_title, new_genre = new
at_most = len(lst)
at_least = 0
while at_least < at_most:
center = (at_least + at_most) // 2
title, genre = lst[center]
os.system("clear")
competition_strings = [new_title, new_genre, "\n" * 10, title, genre]
print("\n".join(x.center(150) for x in competition_strings))
c = getch()
if c == "j": # new movie is worse than this
at_most = center
else: # new movie is better than this
at_least = center + 1
return at_least
修改:我使用以下代码进行了测试。
lst = []
news = [(str(i), str(i)) for i in range(10)]
import random
random.shuffle(news)
for new in news:
print(lst)
lst.insert(determine_points(lst, new), new)
print(lst)